본문 바로가기

ASP.NET Core in .NET 8.0/OMOK GAME

240715 회원 관리 서버 HIVE

프로젝트 구조

Hive.Server/
├── Controllers/
│   └── AuthController.cs
├── DTO/
│   └── UserDto.cs
│   └── RegisterDto.cs
│   └── LoginDto.cs
├── Models/
│   └── User.cs
├── Properties/
├── Repository/
│   └── IUserRepository.cs
│   └── UserRepository.cs
└── Data/
    └── ApplicationDbContext.cs
    └── Migrations/

 

User 클래스

Models/User.cs

namespace Hive.Server.Models
{
    public class User
    {
        public int Id { get; set; }
        public string Email { get; set; }
        public string PasswordHash { get; set; }
        public string Nickname { get; set; }
    }
}

 

회원가입 DTO

DTO/RegisterDto.cs

namespace Hive.Server.DTO
{
    public class RegisterDto
    {
        public string Email { get; set; }
        public string Password { get; set; }
        public string Nickname { get; set; }
    }
}

 

로그인 DTO

DTO/LoginDto.cs

namespace Hive.Server.DTO
{
    public class LoginDto
    {
        public string Email { get; set; }
        public string Password { get; set; }
    }
}

 

회원 DTO

DTO/UserDto.cs

namespace Hive.Server.DTO
{
    public class UserDto
    {
        public int Id { get; set; }
        public string Email { get; set; }
        public string Nickname { get; set; }
    }
}

 

 

Data/ApplicationDbContext.cs

using Microsoft.EntityFrameworkCore;
usinv Hive.Server.Models;

namespace Hive.Server.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {

        }
    }

    public DbSet<User> Users { get; set; }

}

 

 

Repository/IUserRepository.cs

using System.Threading.Tasks;
using Hive.Server.Models;

namespace Hive.Server.Repository
{
    public interface IUserRepository
    {
        Task<User> GetUserByEmailAsync(string email);
        Task<User> CreateUserAsync(User user);
        Task<bool> ValidateUserCredentialsAsync(string email, string password);
    }
}

 

Repository/UserRepository.cs

using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Hive.Server.Models;
using Hive.Server.DataAccess;

namespace Hive.Server.Repository
{
    public class UserRepository : IUserRepository
    {
        private readonly ApplicationDbContext _context;

        public UserRepository(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<User> GetUserByEmailAsync(string email)
        {
            return await _context.Users.SingleOrDefaultAsync(u => u.Email == email);
        }

        public async Task<User> CreateUserAsync(User user)
        {
            _context.Users.Add(user);
            await _context.SaveChangesAsync();
            return user;
        }

        public async Task<bool> ValidateUserCredentialsAsync(string email, string password)
        {
            var user = await GetUserByEmailAsync(email);
            if (user == null)
                return false;

            // Password hashing & validation should be handled properly in production
            return user.PasswordHash == password;
        }
    }
}

 

Controllers/AuthController.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Hive.Server.DTO;
using Hive.Server.Models;
using Hive.Server.Repository;

namespace Hive.Server.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class AuthController : ControllerBase
    {
        private readonly IUserRepository _userRepository;

        public AuthController(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }

        [HttpPost("register")]
        public async Task<IActionResult> Register([FromBody] RegisterDto registerDto)
        {
            if (await _userRepository.GetUserByEmailAsync(registerDto.Email) != null)
            {
                return BadRequest("Email already in use.");
            }

            var user = new User
            {
                Email = registerDto.Email,
                PasswordHash = registerDto.Password, // Hash password in production
                Nickname = registerDto.Nickname
            };

            await _userRepository.CreateUserAsync(user);

            var userDto = new UserDto
            {
                Id = user.Id,
                Email = user.Email,
                Nickname = user.Nickname
            };

            return Ok(userDto);
        }

        [HttpPost("login")]
        public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
        {
            if (!await _userRepository.ValidateUserCredentialsAsync(loginDto.Email, loginDto.Password))
            {
                return Unauthorized("Invalid credentials.");
            }

            var user = await _userRepository.GetUserByEmailAsync(loginDto.Email);
            var userDto = new UserDto
            {
                Id = user.Id,
                Email = user.Email,
                Nickname = user.Nickname
            };

            return Ok(userDto);
        }
    }
}

 

Program.cs

using Microsoft.EntityFrameworkCore;
using Hive.Server.Data;
using Hive.Server.Repository;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseMySql(
        builder.Configuration.GetConnectionString("DefaultConnection"),
        new MySqlServerVersion(new Version(8,3,0))
    ));
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll",
        builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseCors("AllowAll");
app.MapControllers();

app.Run();

 

 

테스트 방법

dotnet tool install --global dotnet-ef

dotnet add package Microsoft.EntityFrameworkCore.Design
 
dotnet ef migrations add InitialCreate
 
dotnet ef database update