Microsoft .NET/ASP.Net & ASP.Net Core

[ASP.NET Core] JWT 토큰 발급·검증 최소 구현 (.NET 8)

전자기린 2026. 11. 10. 00:37

.NET 8 ASP.NET Core에서 JWT를 직접 발급하고 검증하는 최소 구성입니다. 별도 인증 서버 없이 아이디/비밀번호 로그인 API를 만들 때 씁니다.

절차

  1. 패키지 설치
  2. appsettings.json에 키 설정
  3. 토큰 발급 서비스
  4. 검증 등록
  5. 로그인 API와 보호된 API

 

1. 패키지

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

2. 설정

{
  "Jwt": {
    "Issuer": "vgstudio",
    "Audience": "vgstudio-client",
    "Key": "32바이트-이상-충분히-긴-비밀키"
  }
}

대칭키(HS256)는 32바이트 이상이어야 합니다. 키는 소스에 넣지 말고 환경 변수나 사용자 시크릿으로 관리합니다.

3. 토큰 발급

public class TokenService
{
    private readonly IConfiguration _config;
    public TokenService(IConfiguration config) => _config = config;

    public string Create(string userId, string role)
    {
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, userId),
            new Claim(ClaimTypes.Role, role),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };
        var key = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(_config["Jwt:Key"]!));
        var token = new JwtSecurityToken(
            issuer: _config["Jwt:Issuer"],
            audience: _config["Jwt:Audience"],
            claims: claims,
            expires: DateTime.UtcNow.AddHours(1),
            signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256));

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

4. 검증 등록

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!)),
            ClockSkew = TimeSpan.Zero
        };
    });

5. 로그인 API와 보호된 API

app.MapPost("/login", (LoginDto dto, TokenService svc) =>
{
    if (dto.Id != "admin" || dto.Pw != "pass") return Results.Unauthorized();
    return Results.Ok(new { token = svc.Create(dto.Id, "Admin") });
});

app.MapGet("/me", (ClaimsPrincipal user) => user.Identity?.Name).RequireAuthorization();

테스트는 Authorization: Bearer {token} 헤더로 호출합니다.

정리

  1. 키는 32바이트 이상, 소스 밖에 보관
  2. 발급과 검증의 Issuer/Audience/Key를 동일하게
  3. 권한은 [Authorize(Roles = "Admin")]로 제한