티스토리 뷰
로그인과 토큰
사용자가 서비스를 이용하는 동안, 예를 들면 A페이지에서 B페이지로 이동하는 등의 작업을 수행할 때마다 로그인을 요구한다면 사용자 입장에서 불편함을 야기할 수 있다. 그렇기 때문에 실제 로그인 구조에서는 로그인 후에 로그인 상태를 유지하거나, 자동 로그인 등과 같은 기능이 필요하다. 이를 위해 토큰을 도입하여 토큰 기반의 로그인 로직이 구성되었다.
인증(Authentication) vs 인가(Authorization)
인증 (Authentication)
사용자가 자신의 신원을 확인하는 과정.
사용자가 누구인지 사용자의 아이디와 비밀번호, 토큰, 인증서 등을 사용하여 자신을 주장함을 확인한다.
예를 들어, 로그인 과정에서 사용자가 입력한 아이디와 비밀번호가 유효한지 검증하는 것이 인증의 예이다.
인증이 완료되면 사용자는 시스템에 접근할 권한을 획득한다.
인가 (Authorization)
사용자에게 특정 자원에 대한 접근 권한을 부여하는 과정.
즉, 인증된 사용자가 특정 작업을 수행할 수 있는지를 결정하는 것이다.
예를 들어, 사용자가 특정 웹 페이지에 접근할 수 있는 권한이 있는지를 확인하여 접근을 허용 또는 거부하는 것이 인가의 예이다.
인가는 인증이 완료된 후에 이루어지며, 인증된 사용자의 권한에 따라 접근 권한이 부여된다.
💡 인증 - 사용자가 특정 서비스에 일정 권한이 주어진 사용자임을 아이디와 패스트워드 등을 통해서 확인하는 과정
💡 인가 - 인증받은 사용자가 접근 권한을 확인하는 과정
JWT란?
JWT란 Json Web Token의 약자로, 인증 및 인가를 위한 웹 표준으로 클라이언트와 서버 간에 안전하게 정보를 전송하기 위한 토큰 기반의 인증 방식이다.
세션 방식의 로그인은 서버가 복잡한 구성과 환경에서 사용자의 로그인 상태를 기억해야 하는 등의 복잡한 설계가 필요하다. 이에 반해, JWT 방식은 이러한 부담 없이 인가를 구현하기 위해 고안된 방식이다.
JWT 구성요소
Header
: JWT 토큰의 타입과 해싱 알고리즘 정보가 담겨있다.
- typ(토큰 타입): JWT 고정
- alg(암호화 규칙): Signature 값을 만드는 데 사용될 알고리즘이 지정된다. HS256 등 여러 암호화 방식 중 하나를 지정할 수 있다. Header와 Payload 그리고 서버에 감춰놓은 Secret Key, 이 셋을 설정한 알고리즘에 넣고 돌린 값이 바로 Signature 값이다.
- 암호화 알고리즘은 단방향으로 계산되기 때문에 서버에 감춰놓은 Secret Key를 찾아낼 방법이 없다.
Payload
: 정보 데이터가 담겨있다. Base 64로 디코딩해 보면 JSON 형식으로 여러 정보들이 들어있는 것을 확인할 수 있다.
토큰 발급 출처, 토큰의 유효성, 토큰 허용 범위 등과 같이 토큰에 담긴 사용자 정보 등의 데이터를 Claim이라고 한다.
필요한 정보들이 토큰에 담겨서 서버에 전달하니 서버 측에서는 일일이 데이터베이스를 찾아보지 않아도 인증/인가를 확인할 수 있다.
Signature
: 토큰의 무결성을 검증하기 위한 데이터로 Header와 Payload를 인코딩하여 미리 정의된 Secret Key를 사용하여 Signature를 생성한다. 이를 통해 토큰이 변조되었는지 여부를 검증할 수 있다.
💡 즉, 서버 측에서 클라이언트로 전달받은 JWT의 Header와 Payload, 그리고 서버에 감춰놓은 Secret Key를 알고리즘화 하여 나온 값과 JWT의 Signature 값이 일치하는 지를 확인한다.
세션 vs JWT
JWT는 세션의 자리를 완전히 대체할 수는 없다. JWT는 Stateless한 특징을 가지고 있어 서버에 상태를 저장하지 않고 토큰 자체에 필요한 정보를 포함하고 있는 반면, 세션은 서버에 정보를 저장하고 클라이언트에 세션 ID를 부여하여 서버와 클라이언트 간의 상태를 유지하는 Stateful한 방식을 채택한다.
세션은 서버에 저장소가 있기 때문에 서버에서 세션을 관리하고 클라이언트의 요청에 따라 세션을 조작할 수 있어, 예를 들어 여러 기기에서 동시 로그인을 제어하거나 기존 세션을 강제로 종료할 수 있다는 장점이 있다. 반면, JWT는 토큰 자체가 모든 정보를 가지고 있기 때문에 토큰을 추적하는데 어려움이 있을 수 있다.
JWT에서는 보안을 강화하기 위해 유효기간을 짧게 설정하는 것이 일반적이다. 그러나 이렇게 유효기간이 짧은 토큰을 사용하면 사용자가 몇 분 후에 다시 로그인을 해야하는 불편함이 발생할 수 있다. 이를 보완하기 위해 일반적으로 로그인 후에는 access 토큰과 refresh 토큰 두 가지를 발급하여 사용한다. access 토큰은 짧은 유효기간으로, refresh 토큰은 평균 2주 정도의 긴 유효기간으로 설정하여 사용자가 자주 로그인을 다시 하지 않아도 되도록 한다.
서버는 클라이언트에게 access 토큰과 refresh 토큰을 발급하고, refresh 토큰의 상응값을 서버의 데이터베이스에도 저장한다. 유저의 access 토큰 수명이 다하면 refresh 토큰을 보내며 서버는 전달받은 refresh 토큰과 데이터베이스에 저장된 값을 대조해보고 일치하면 새로운 access 토큰을 발급해 준다.
즉 refresh 토큰을 안전하게 잘 보관만 한다면 access 토큰이 만료될 때마다 재로그인 필요 없이 새로운 토큰을 요청할 수 있다.
출처
Hashing Algorithm Overview: Types, Methodologies & Usage | Okta
'Dev > Web' 카테고리의 다른 글
[Web] OAuth의 개념와 동작원리 (0) | 2023.04.14 |
---|---|
[Web] CORS란 무엇인가? (0) | 2023.04.08 |