인증 (Authentication)
로그인
아이디랑 패스워드 등을 통해서 말 그대로 사용자임을 인증 받음
인가 (Authorization)
한 번 인증 받은 사용자가 (로그인 하고 나서) 활동을 할 때 내가 로그인 되어있음을 알아보고 허가해주는 것
오늘 다룰 내용은 인가에 관련된 기술
즉 Session이란
Session ID를 사용해서 어떤 사용자가 서버에 로그인 되어있음이 지속되는 상태
- xxxxxxx.zzzzzz.yyyyyy 형식으로 되어있다.
- eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- 예시 사이트 Click
- 디코딩 해보면 두가지 정보가 담겨져있다.
{ "alg": "HS256", "typ": "JWT" }
alg
알고리즘의 약자, 3번 서명 값을 만드는데 사용된 알고리즘이 지정된다.
typ
type, 언제나 JWT가 들어간다. 고정값
- Base64로 디코딩해보면 JSON 형식으로 정보들이 들어있다
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
- Claim : 이렇게 토큰에 담긴 사용자 정보등의 데이터
- 이 토큰을 누가 누구에게 발급했는지,
- 언제까지 유효한지,
- 서비스가 사용자에게 이 토큰을 통해 공개하기 원하는 내용
(사용자 닉네임, 서비스상의 레벨, 관리자 여부 등)
이후 요청마다 사용자가 서버에 토큰을 보내고, 토큰에 사용자의 정보가 담겨져있기 때문에 서버가 요청마다 일이 DB를 찾아야하는 부담이 줄어든다.
- 서명 값
서버는 요청에 토큰이 실려오면 1,2번(HEADER, PAYLOAD)의 값을 서버의 비밀 키와 함께 돌려봐서 계산된 결과값이 3번 서명 값과 일치하는지 확인한다.
-> 2번의 PAYLOAD 값이 악의로 수정되는 것을 막기 위함!
서버가 사용자들의 상태를 따로 기억을 해 둘 필요 없이, 비밀 값만 가지고 있으면 요청이 들어올 때마다 토큰을 스캔해서 인가해주면 된다.
이처럼 시간에 따라 바뀌는 어떤 상태값을 안 갖는 걸 stateless하다고 한다.
토큰은 stateless
세션은 stateful
그렇다면 JWT가 Session보다 우월한가? ❌NO❌
세션방식은 PC에서 로그인 된 사용자가 스마트폰으로 로그인하면, 기존의 PC의 세션을 종료시키는 등 기억하는 대상을 언제든 제어할 수 있다.
토큰은 한번 줘버린 토큰을 뺏을 수 없다. 서버가 토큰을 쥐고 있을 필요가 없으니 편리하긴 하지만 통제할 수 없게 된다.
❗ 탈취된 토큰을 무효화할 수 없으니 보안에 취약한 점도 생긴다.
이를 방지하기 위해 토큰을 두 개를 발급하는 방법이 있다
. 수명이 몇 시간, 몇 분 이하로 짧은 access 토근(인가용 토큰)
. 보통 2주로 주는 refresh 토큰(access 토큰 재발급 용)
1. 서버는 refresh토큰을 발급할 때 상응값을 DB에도 저장한다.
2. 손님은 acess 토큰의 수명이 다하면 refresh 토큰을 보낸다.
3. 서버는 refresh 토큰을 DB와 대조해보고 맞다면 새 access 토큰을 발급해준다.
‼ refresh 토큰만 안전하게 관리하면 된다. refresh 토큰이 탈취당했을 경우 DB에서 refresh 토큰 정보를 지워서 access 토큰 갱신을 막으면 된다.
💥 한계 : access 토큰이 잠시나마 살아있는 동안은 바로 차단할 방법이 없다.