c#

ASP.NET Core JWT 기반 인증 구현 가이드

개발에대해 2025. 9. 29. 11:18
반응형

 

ASP.NET Core JWT 기반 인증 구현 가이드

 

1. JWT 인증이란?

JWT(Json Web Token)은 사용자 인증과 정보 교환을 위해 널리 사용되는 안전한 토큰 기반 인증 방식입니다. 서버는 사용자가 로그인 시 JWT를 발급하고, 클라이언트는 이후 요청 시 해당 토큰을 포함시켜 인증을 진행합니다. ASP.NET Core Web API에서는 JWT를 이용해 RESTful API 보호 및 권한 관리가 가능합니다.

2. 개발 환경 준비

JWT 기반 인증을 구현하기 위해 필요한 환경은 다음과 같습니다.

  • .NET 8 / .NET 7 SDK (최신 LTS 권장)
  • Visual Studio 2022 또는 Visual Studio Code
  • Postman 또는 Swagger UI (API 테스트용)
  • NuGet 패키지: Microsoft.AspNetCore.Authentication.JwtBearer

JWT 패키지는 NuGet에서 설치 가능하며, 터미널에서 다음 명령어로 설치합니다.

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

3. JWT 설정과 시크릿 키 관리

토큰 서명(Signing)에 사용할 시크릿 키를 안전하게 관리하는 것이 중요합니다. appsettings.json에 시크릿 키를 저장하고, Program.cs에서 읽어와 설정합니다.

{
  "JwtSettings": {
    "SecretKey": "여기에_복잡한_문자열_입력",
    "Issuer": "MyApi",
    "Audience": "MyApiUsers",
    "ExpiryMinutes": 60
  }
}

4. Program.cs에서 JWT 인증 구성

ASP.NET Core 미들웨어를 사용하여 JWT 인증을 설정합니다.

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

var jwtSettings = builder.Configuration.GetSection("JwtSettings");
var key = Encoding.ASCII.GetBytes(jwtSettings["SecretKey"]);

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = jwtSettings["Issuer"],
        ValidAudience = jwtSettings["Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ClockSkew = TimeSpan.Zero
    };
});

builder.Services.AddControllers();
var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

위 코드로 API가 JWT 토큰을 검증하도록 설정됩니다. UseAuthentication()UseAuthorization() 순서를 지키는 것이 중요합니다.

5. 로그인 API 및 JWT 발급

사용자가 로그인하면 JWT를 발급하는 컨트롤러 예제입니다.

using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly IConfiguration _config;

    public AuthController(IConfiguration config)
    {
        _config = config;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginRequest request)
    {
        // 사용자 검증 로직 (예: DB 조회)
        if(request.Username == "admin" && request.Password == "1234")
        {
            var token = GenerateJwtToken(request.Username);
            return Ok(new { Token = token });
        }
        return Unauthorized();
    }

    private string GenerateJwtToken(string username)
    {
        var jwtSettings = _config.GetSection("JwtSettings");
        var key = Encoding.ASCII.GetBytes(jwtSettings["SecretKey"]);

        var tokenHandler = new JwtSecurityTokenHandler();
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Name, username)
            }),
            Expires = DateTime.UtcNow.AddMinutes(double.Parse(jwtSettings["ExpiryMinutes"])),
            Issuer = jwtSettings["Issuer"],
            Audience = jwtSettings["Audience"],
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }
}

public class LoginRequest
{
    public string Username { get; set; }
    public string Password { get; set; }
}

6. 보호된 API 만들기

JWT 인증을 적용하여 특정 API는 로그인한 사용자만 접근할 수 있도록 제한할 수 있습니다.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class ValuesController : ControllerBase
{
    [HttpGet]
    [Authorize]
    public IActionResult GetValues()
    {
        return Ok(new string[] { "Value1", "Value2", "Value3" });
    }
}

위 코드에서 [Authorize] 어트리뷰트를 추가하면, 클라이언트는 반드시 유효한 JWT 토큰을 요청 헤더에 포함해야 API 접근이 가능합니다.

7. 테스트와 검증

Postman이나 Swagger를 이용하여 JWT 발급 후 보호된 API를 호출해 테스트할 수 있습니다. Authorization 헤더에 Bearer {token} 형태로 토큰을 포함시켜 요청하면 됩니다.

또한, 토큰 만료 시나 잘못된 토큰을 사용할 경우 401 Unauthorized 응답이 발생하는 것을 확인할 수 있습니다.

8. 실무 적용 팁

  • 시크릿 키는 절대 코드에 직접 노출하지 말고, 환경변수 또는 Azure Key Vault 등 안전한 장소에 저장하세요.
  • 토큰 만료 시간(Expiry)을 상황에 맞게 설정하고, Refresh Token 전략도 고려하면 보안 강화에 도움이 됩니다.
  • Swagger 테스트 시 JWT 인증을 적용할 수 있도록 Swagger 설정에서 Bearer Token 옵션을 활성화하세요.
  • 권한(Role) 기반 API 접근 제어를 추가하면, 관리자가 특정 리소스만 접근할 수 있게 구현할 수 있습니다.

9. 마무리

이번 글에서는 ASP.NET Core에서 JWT 기반 인증을 구현하는 방법을 단계별로 살펴보았습니다. 로그인 API 생성, JWT 발급, 보호된 API 접근, 실무 보안 팁까지 다루었습니다. 이를 기반으로 안전하고 확장 가능한 RESTful API를 개발할 수 있으며, 향후 OAuth2, IdentityServer 등과 결합하면 더욱 강력한 인증/권한 관리 시스템을 구현할 수 있습니다.

반응형