-
Notifications
You must be signed in to change notification settings - Fork 6
Usage_JWT
JWT(Json Web Tokens) 을 이용하여 엑세스 토큰(Access Token)을 발급하고 인증 하는 방법입니다.
JWT 를 구성하기 위해 Startup.cs 파일에 아래의 코드를 추가합니다. 그리고 appsettings.json 파일에 설정 정보를 설정합니다.
appsettings.json 파일에 설정 정보를 설정합니다.
{
"authentication": {
"key": "VERY_VERY_SECURE_KEY",
"issuer": "http://localhost:12345"
}
}
Startup.cs 파일에 아래의 코드를 추가하여 JWT 인증을 활성화 합니다.
ConfigureServices
메서드에 아래의 코드를 추가하여 JWT 에서 토큰 유효성 검사를 위한 매개변수를 서비스에 등록 합니다.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcWithWebSocketIo();
var jwtTokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = _configuration["authentication:issuer"],
ValidAudience = _configuration["authentication:issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["authentication:key"]))
};
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearerWithWebSocketIo(options =>
{
options.TokenValidationParameters = jwtTokenValidationParameters;
});
}
등록된 서비스를 사용하기 위해 Configure
메서드에서 아래의 코드를 추가하여, 웻소켓과 인증 미들웨어를 활성화 합니다.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseWebSockets()
.UseWebSocketIo()
.UseAuthentication()
.UseMvc();
}
JwtController.cs
컨트롤러 파일을 생성한 후, WebSocketIoController
를 상속합니다.
Authorize
특성을 컨트롤러에 선언하였으며, AuthenticationSchemes
매개변수를 이용하여 웹을 통한 JWT 인증과 웹소켓을 이용한 JWT 인증 모두를 활성화 합니다.
[Route("/api/jwt")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme + "," + WebSocketIoDefaults.AuthenticationScheme)]
public class JwtController : WebSocketIoController
{
private readonly IWebSocketIo _webSocketIo;
private readonly IConfiguration _configuration;
public JwtController(IWebSocketIo webSocketIo,
IConfiguration configuration) : base(webSocketIo)
{
_webSocketIo = webSocketIo;
_configuration = configuration;
}
}
이제 JWT 를 발급하는 Login
메서드와 인증된 사용자만 호출이 가능한 Me
메서드를 만듭니다.
[Route("login")]
[AllowAnonymous]
public IActionResult Login(LoginModel model)
{
return Ok(new
{
AccessToken = BuildToken()
});
}
[Route("me")]
public IActionResult Me()
{
return Ok(new
{
Name = User.FindFirstValue(ClaimTypes.NameIdentifier),
Email = User.FindFirstValue(ClaimTypes.Email)
});
}
private string BuildToken()
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, "admin"),
new Claim(JwtRegisteredClaimNames.Email, "[email protected]"),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["authentication:key"]));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_configuration["authentication:issuer"],
_configuration["authentication:issuer"],
claims: claims,
expires: DateTime.Now.AddYears(1),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
아래의 bash 스크립트를 실행하여 Access Token 을 발급 받습니다.
curl http://localhost:12345/api/jwt/login
위의 명령을 실행하면 아래와 같이 JSON 결과를 반환하며, accessToken
의 값은 매번 바뀔 수 있습니다.
{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBudHJlZXYuY29tIiwiZXhwIjoxNTcwNzc1NDQwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjEyMzQ1IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoxMjM0NSJ9._rq2NHxnmtYGYOVjYV8j8xAZVWbjcaRnH3t429vKVd0"}
발급받은 Access Token 을 이용하여 내 정보를 조회하는 me
API 를 호출합니다. 아래의 Authorization: Bearer
이후의 값은 발급받은 Access Token 값 입니다.
curl http://localhost:12345/api/jwt/me -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBudHJlZXYuY29tIiwiZXhwIjoxNTcwNzc1NDQwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjEyMzQ1IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoxMjM0NSJ9._rq2NHxnmtYGYOVjYV8j8xAZVWbjcaRnH3t429vKVd0'
위 명령을 실행하면 아래와 같이 내 정보를 반환하여 표시합니다.
{
"name":"admin",
"email":"[email protected]"
}
자바스크립트 또는 노드(Node) 환경에서 테스트해 볼 수 있지만, 간단하게 웹 브라우저의 개발자 도구를 이용하여 웹소켓 테스트를 합니다.
먼저 크롬(또는 개발자 도구를 지원하는 웹 브라우저) 브라우저를 실행하고, F12 키 또는 브라우저의 메뉴에서 '개발자 도구'를 실행합니다. 그리고 아래의 자바스크립트를 복사하여 붙여 넣습니다. (단, 새 탭을 열어 완전히 비어있는 탭이어야 합니다.)
먼저 웹소켓 객체를 생성한 후, 소켓이 서버와 연결이 되면 /api/jwt/login
을 호출하고 그 결과를 콘솔에 표시합니다.
var socket = new WebSocket('ws://localhost:12345');
socket.onopen = function() { socket.send(JSON.stringify({ path: '/api/jwt/login' })); }
socket.onmessage = function(event) { console.log(event.data); }
위 명령을 실행하면 아래와 같은 JSON 결과가 콘솔에 표시됩니다.
{
"id":null,
"emitName":null,
"type":0,
"statusCode":200,
"data":{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBudHJlZXYuY29tIiwiZXhwIjoxNTcwNzc2NDM3LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjEyMzQ1IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoxMjM0NSJ9.g8iX7yJHYuDXHYjuCibHLkBXiGN81xv1Ny-qGYfPvA4"}
}
위 결과의 accessToken
값을 이용하여 내 정보를 반환하는 me
API 를 호출합니다.
socket.send(JSON.stringify({ path: '/api/jwt/me', headers: { 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBudHJlZXYuY29tIiwiZXhwIjoxNTcwNzc2NDM3LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjEyMzQ1IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoxMjM0NSJ9.g8iX7yJHYuDXHYjuCibHLkBXiGN81xv1Ny-qGYfPvA4' }}));
위 명령을 실행하면 아래와 같이 내 정보를 반환하여 콘솔에 표시합니다.
{
"id":null,
"emitName":null,
"type":0,
"statusCode":200,
"data":{
"name":"admin",
"email":"[email protected]"
}
}