dotnet add package Swashbuckle.AspNetCore
// Controllers/HomeController.cs
[Route("api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
public class TestRequest
{
public required string testMessage { get; set; }
public required int testNumber { get; set; }
}
[HttpGet("/")]
public string Index()
{
return "hello, world!!";
}
[HttpPost("test")]
public string Test(TestRequest request)
{
return $"test message: {request.testMessage}. testNum: {request.testNumber}";
}
}// Program.cs
namespace aspdotnet
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// 컨트롤러 서비스 등록
builder.Services.AddControllers();
// Swagger 서비스 등록
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// 개발 환경에서 Swagger UI 활성화
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// HTTPS 리디렉션 활성화
app.UseHttpsRedirection();
// 컨트롤러 라우팅 활성화
app.MapControllers();
app.Run();
}
}
}// Model/User.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace aspdotnet.Model
{
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserNo { get; set; }
public required string UserID { get; set; }
public required byte[] PasswordHash { get; set; }
public required byte[] PasswordSalt { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
}dotnet add package Microsoft.EntityFrameworkCore.Sqlite// Data/AppDbContext.cs
using aspdotnet.Model;
using Microsoft.EntityFrameworkCore;
namespace aspdotnet.Data
{
public class AppDbContext: DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.HasIndex(u => u.UserID)
.IsUnique();
}
}
}using aspdotnet.Data;
using Microsoft.EntityFrameworkCore;
namespace aspdotnet
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// 컨트롤러 서비스 등록
builder.Services.AddControllers();
// Swagger 서비스 등록
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// SQLite 서비스 등록
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("app")));
var app = builder.Build();
// 애플리케이션 시작시 DB 자동 생성
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
db.Database.EnsureCreated();
}
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
}
}
}options.UseSqlite(builder.Configuration.GetConnectionString("app"))); DB이름을 설정파일에서 가져오게 돼있습니다. 이를 위해 설정파일에 DB이름을 넣어주어야 합니다.// appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"app": "Data source=app.db"
}
}
using aspdotnet.Data;
using aspdotnet.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
namespace aspdotnet.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly AppDbContext _context;
public AuthController(AppDbContext context)
{
_context = context;
}
public class SignupRequest
{
public required string UserID { get; set; }
public required string Password { get; set; }
public required string PasswordConfirm { get; set; }
}
[HttpPost("signup")]
public IActionResult Signup(SignupRequest request)
{
if (request.Password != request.PasswordConfirm)
return BadRequest("Passwords do not match");
// for Test api
{
if (request.UserID == "string")
{
return Ok("signup api running well");
}
if (!TestCode(request))
{
return BadRequest("Please use test credentials starting with 'test' for UserID and 'qwer' for Password");
}
}
// check existing user
if (_context.Users.Any(u => u.UserID == request.UserID))
return Conflict("Username already exists");
CreatePasswordHash(request.Password, out var hash, out var salt);
var user = new User
{
UserID = request.UserID,
PasswordHash = hash,
PasswordSalt = salt
};
_context.Users.Add(user);
_context.SaveChanges();
return Ok("Signup successful");
}
bool TestCode(SignupRequest request)
{
if (!request.UserID!.StartsWith("test"))
{
return false;
}
if (!request.Password!.StartsWith("qwer"))
{
return false;
}
return true;
}
private static void CreatePasswordHash(string password, out byte[] hash, out byte[] salt)
{
salt = RandomNumberGenerator.GetBytes(16);
hash = Rfc2898DeriveBytes.Pbkdf2(password, salt, 100_000, HashAlgorithmName.SHA256, 32);
}
}
}hash = Rfc2898DeriveBytes.Pbkdf2(password, salt, 100_000, HashAlgorithmName.SHA256, 32);/api/Auth/signup: 회원가입/api/Auth/login: 로그인/api/User/info: 회원 정보(회원 번호, 회원 id)