-
Token AuthenticationBack-end 2022. 2. 23. 18:48
웹에서 자주 사용되는 토큰과 그에 기반한 인증방식을 정리하였습니다.
< 토큰 기반 인증 사용 이유 >
세션 기반 인증은 서버(혹은 DB)에 유저 정보를 담는 인증 방식이었습니다. 매 요청마다 유저를 확인하기 위해 서버(혹은 DB)를 살펴봐야하고, 유저가 많아질수록 서버에 부담이 많이가기 때문에 토큰 기반 인증을 사용하게 되었습니다.
토큰 기반 인증은 토큰을 클라이언트에서 보관하기 때문에 서버에 가해지는 부담이 줄어들게 됩니다.
< 토큰(Token) >
토큰은 일종의 권리를 주는 것입니다. 게시글을 포스팅 할 수 있는 권리, 댓글을 남길 수 있는 권리 등.
인증 토큰은 도장이 찍힌 티켓과 같습니다. 토큰이 유효하다면 사용자는 계속해서 웹사이트에 액세스할 수 있습니다. 사용자가 로그아웃하거나 앱을 종료하면 토큰도 무효화됩니다.
클라이언트는 XSS, CSRF등의 공격에 노출이 될 수 있으니 민감한 정보를 담고 있으면 안됩니다. 하지만 이 중요한 토큰을 클라이언트에 맡기는 이유는 다음과 같습니다.
=> 토큰은 유저 정보를 암호화한 상태로 담을 수 있고, 암호화했기 때문에 클라이언트에 담을 수 있습니다.토큰 이용사례)
- Gmail 인증서버에 로그인 정보(아이디, 비밀번호)를 제공한다
- 성공적으로 인증 시 JWT를 발급받는다
- A 앱은 JWT를 사용해 해당 유저의 Gmail 이메일을 읽거나 사용할 수 있다
< JWT(Json Web Token) >
현재 웹사이트에서는 여러 토큰 중에서도 Json Web Token을 가장 많이 쓰고 있습니다.
Json 포맷으로 사용자에 대한 정보를 저장합니다.< JWT 구조 > :
A A A A . B B B B . C C C C
- Header : AAAA
- 어떤 종류의 토큰인인지(지금은 JWT)
- 어떤 알고리즘으로 암호화할지
{ "alg": "HS256", "typ": "JWT" }
- Payload : BBBB
- 유저의 정보
- 어떤 정보에 접근 가능한지에 대한 권한
- 기타 정보
=> Payload에 민감한 정보는 되도록 담지 않는 것이 좋습니다.(암호화 되어있지만, 혹시 토큰이 탈취될 수 있기 때문에)
{ "sub": "someInfornation", "name": "Lee", "iat": 15367854 }
- Signature : CCCC
- Header, Payload를 base64인코딩한 값과 salt의 조합으로 암호화된 값
// HMAC SHA256 알고리즘(암호화 방법 중 하나)을 사용 : HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
< JWT 종류 > :
- Access Token : 보호된 정보들(유저의 이메일, 연락처, 사징 등)에 접근할 수 있는 권한부여에 사용됩니다.
- Refresh Token : Access Token의 유효기간이 만료되었을 경우, Access Token을 재발급 받는 데 사용됩니다.
=> 클라이언트가 처음 인증을 받게 될 때(로그인 시), access, refresh token 두 가지를 다 받지만, 실제로 권한을 얻는 데 사용하는 토큰은 access token입니다. 하지만 access token이 탈취되었을 경우를 대비해 access token의 유효기간을 비교적 짧게 설정하고, refresh token을 이용해 재발급 받는 식으로 작동합니다.
+. Refresh Token 또한 탈취되었을 경우를 대비해 유저의 편의보다 정보를 지키는 것이 더 중요한 웹사이트들은 Refresh Token 없이 Access Token만 부여하는 경우도 있습니다.
+. Refresh Token과 Access Token이 같은 정보를 담을 필요는 없습니다.
< 토큰 인증 작동 방식 >
- 클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보냅니다.
- 서버에서 아이디/비밀번호가 일치하는지 확인하고, 클라이언트에게 보낼 토큰을 생성합니다.
- Access / Refresh 토큰을 생성합니다. - 생성한 토큰을 클라이언트에게 전달하고, 클라이언트는 받은 토큰을 저장합니다.
- 저장하는 위치는 local storage, cookie, react의 state등 다양하게 저장할 수 있습니다. - 이후 토큰을 이용해 서버에 요청을 보낼 때마다 HTTP헤더에 토큰을 담아 보냅니다.
- HTTP의 authorization헤더에 토큰을 담아 보냅니다.
- bearer authorization이용 : https://learning.postman.com/docs/sending-requests/authorization/#bearer-token
=> Header: { Authorization: "Bearer JWT_TOKEN" } - 서버는 토큰을 해독하여 적절한 응답을 보내줍니다.
< 토큰 기반 인증의 장점 >
- Statelessness & Scalability (무상태성 & 확장성)
- 서버는 클라이언트에 대한 정보를 저장할 필요가 없습니다. (토큰 해독이 되는지만 판단)
- 클라이언트는 새로운 요청을 보낼 때마다 토큰을 헤더에 포함시키면 됩니다.
=> 서버를 여러개 가지고 있는 서비스라면 더더욱 유용합니다 (같은 토큰으로 여러 서버 인증 가능) - 안전성
- Signature을 받은(암호화된) 토큰을 사용하고, 암호화 키를 노출할 필요가 없기 때문에 안전합니다. - 어디서나 생성 가능하다
- 토큰을 확인하는 서버가 꼭 토큰을 만들어야 하는 법은 없습니다. 토큰 생성용 서버를 만들거나, 다른 회사에서 토큰 관련 작업을 맡기는 것 등 다양한 활용이 가능합니다.
'Back-end' 카테고리의 다른 글
OAuth 2.0 (0) 2022.02.23 Cookie & Session (1) 2022.02.22 Introduction: Security, Authentication, and Authorization (0) 2022.01.14 What is the Back-End? (0) 2021.11.02