2023. 1. 2. 00:00ㆍASPNET/ASPNET 7
기존에 TokenGenerator 를 통해서 Create 시에 Guid 를 이용해 token 을 생성했다.
이 token 을 이용하는 것도 단순히 사용하기에는 좋은 방법이다.
하지만 우리는 user 정보등을 token 에 포함하여 사용하고 싶을 수 도 있다.
JWT (Json Web Token) 가 이러한 문제를 해결해 준다.
그래서 이제 여기서는 TokenGenerator 를 통해 JWT 를 발행 하는 방법을 알아볼것이다.
Shared/Interfaces/ITokenGenerator.cs
using ApiServer.Shared.Injectables;
namespace ApiServer.Shared.Interfaces;
public interface ITokenGenerator : ISingleton
{
string Create(string id, string role = "user");
string CreateRefreshToken();
}
Token config 을 설정하기 위해 TokenManagement 를 appsettings 에 설정하고
관련 class 를 Shared/Models 밑에 만든다.
appsettings.json
...
"TokenManagement": {
"Secret": "Any String used to sign and verify JWT Tokens, Replace this string with your own Secret",
"Issuer": "ApiServer",
"Audience": "ApiServer",
"AccessExpiration": 30,
"RefreshExpiration": 1440
}
...
Shared/Models
namespace ApiServer.Shared.Models;
public class TokenManagement
{
public string Secret { get; set; } = string.Empty;
public string Issuer { get; set; } = string.Empty;
public string Audience { get; set; } = string.Empty;
public int AccessExpiration { get; set; }
public int RefreshExpiration { get; set; }
}
JwtBearer token 관련 library 를 사용하기 위해서 다음 package 를 설치 한다.
개발자 명령 프롬프트로 이동
Ctrl + ` 또는 View --> Terminal click --> 개발자 명령 프롬프트로 이동
개발자 명령 프롬프트에서 RestApiServerWebApp 프로젝트 폴더로 이동
**이미 프로젝트 폴더에 있다면 이동하지 않아도 된다. **
(현재 [솔루션명].sln 파일이 있는 폴더라면 [프로젝트명].csproj 파일이 있는 폴더로 이동)
다음 실행
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
Shared/Utility/TokenGenerator.cs
using ApiServer.Shared.Interfaces;
using Microsoft.IdentityModel.Tokens;
using System.Dynamic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace ApiServer.Shared.Utility;
public class TokenGenerator : ITokenGenerator
{
private readonly IConfiguration _configuration;
public TokenGenerator(IConfiguration configuration)
{
_configuration = configuration;
}
public string Create(string id, string role = "user")
{
dynamic token = new ExpandoObject();
var tokenSection = _configuration.GetSection("TokenManagement");
token.Secret = tokenSection.GetValue<string>("Secret");
token.Issuer = tokenSection.GetValue<string>("Issuer");
token.Audience = tokenSection.GetValue<string>("Audience");
token.AccessExpiration = tokenSection.GetValue<int>("AccessExpiration");
token.RefreshExpiration = tokenSection.GetValue<int>("RefreshExpiration");
if (token is null) throw new Exception("TokenManagement configuration need. check your configuration");
var now = DateTime.UtcNow;
var claims = new[]
{
new Claim("Name", id),
new Claim("Role", role),
new Claim("Ticks", now.AddMinutes(token.AccessExpiration).Ticks.ToString())
};
var jwtToken = new JwtSecurityToken(
token.Issuer,
token.Audience,
claims,
expires: now.AddMinutes(token.AccessExpiration),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Secret)), SecurityAlgorithms.HmacSha512Signature));
return new JwtSecurityTokenHandler().WriteToken(jwtToken);
}
public string CreateRefreshToken() => Guid.NewGuid().ToString("N");
}
이제 login.cs 도 수정하자
Features/User/Login.cs
...
public class Response
{
public bool Result { get; set; }
public Error? Error { get; set; }
public string? AccessToken { get; set; }
public string? RefreshToken { get; set; } // 추가
}
...
public class CommandHandler : IRequestHandler<Command, Response>
{
private readonly ITokenGenerator _tokenGenerator;
// ITokenGenerator 를 Constructor injection
public CommandHandler(ITokenGenerator tokenGenerator)
{
_tokenGenerator = tokenGenerator;
}
public Task<Response> Handle(Command request, CancellationToken cancellationToken)
{
var response = new Response { Result = false };
string? accessToken = null;
string? refreshToken = null;
if (request.Pasword == "1234")
{
accessToken = _tokenGenerator.Create(request.Id); // jwt Token 생성)
refreshToken = _tokenGenerator.CreateRefreshToken();
response.Result = true;
}
else
{
response.Error = new Error()
{
Code = "02",
Message = $"Login Failed, check your password"
};
}
response.AccessToken = accessToken;
response.RefreshToken = refreshToken;
return Task.FromResult(response);
}
}
swagger 를 통해 accesstoken 과 refreshtoken 이 제대로 생성되는지 확인해 보자.
위와 같이 accessToken 과 refreshToken 이 생성되는걸 볼 수 있다.
accessToken 은 내부에 claim 을 통해 user 관련 정보가 들어 있는 JWT Token 이다.
refreshToken 은 guid 형태로 만들어진 token 이다.
관련영상
'ASPNET > ASPNET 7' 카테고리의 다른 글
Rest API Template 만들기 - EP 07 (EF Core - Migration and Update) (0) | 2023.01.09 |
---|---|
Rest API Template 만들기 - EP 06 (Authentication, Authorization with jwt) (0) | 2023.01.05 |
Rest API Template 만들기 - EP 04 (Logger Customize, Trace) (0) | 2022.12.29 |
Rest API Template 만들기 - EP 03 (Dependency Injection, Scrutor) (0) | 2022.12.26 |
Rest API Template 만들기 - EP 02 (Vertical Slice, MediatR) (0) | 2022.12.22 |