특징
- 브라우저에 저장하기 때문에 서버 리소스에 부담 없다.
- 서버 확장성(Scalability): Scaling시에도, 서버는 Stateless하기 때문에 토큰 Verification만 수행하면 된다.
- 보안성: Verification을 수행하는데 Server의 비밀키가 사용된다.
- 확장성(Extensibility): 로그인 분야가 사용되는 영역의 확장을 의미한다. OAuth같은 경우 Google, Facebook과 같은 소셜 계정을 이용해 다른 곳에 로그인 가능하다.
- CORS
- 단일 도메인에서만 처리할 수 있도록 했던 세션에서는 CORS문제가 있다. 서비스 규모가 커지면 다른 디바이스나 도메인과 호환을 하게 된다. 이 때 토큰을 사용하게 되면 다른 도메인에서도 토큰의 유효성 검사를 진행한 후에 토큰만 유효하다면 정상처리하면 된다.
- 이런 구조를 통해 assets 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설계할 수 있다고 한다(?)
- 클라이언트가 상태를 들고있다는 점은 쿠키와 같지만, 토큰의 시그니처가 서버의 secret key로 암호화가 되어있다는 점이 다르다.
고려하고 있어야 할 점
- 저장할 필드에 따라 Token이 커질 수 있다. - 일반적으로 세션ID보다 길다고 함
- XSS 공격으로 토큰이 탈취 당할 수 있어 민감한 정보 포함시키지 않아야 한다.
- 클라이언트 컴퓨터가 탈취(해킹)당할 경우 문제
- 액세스 토큰과 리프레시 토큰으로 해결
- JWT : 서버측에 token blacklist 를 관리하게 될 경우 서버쪽 메모리를 사용할 가능성이 있다.
Access Token, Refresh Token
: 클라이언트 컴퓨터가 탈취당할 경우를 대비
- 유효기간이 짧은 액세스 토큰에서 유효기간이 다 되면 유저에게 ID/PW를 물어보는게 아니고 refresh token을 통해 서버에게 액세스 토큰을 재발행 받는다.
- 만약 액세스 토큰 유효기간이 다되고, refresh로 재발행 받으려 할 때 client가 탈취당한걸 서버가 알고있을 경우, 해당 id로는 액세스 토큰을 발급받지 못하도록 막음
- 이 방식의 단점
- 액세스 토큰 재발행 시 매번 서버에 접속 -> 부하
- 액세스 토큰 유효기간 끝날때까지는 여전히 무방비
과정
- 유저 로그인 시 Signed token(액세스 토큰)을 생성 후 암호화 할 secret key를 통해 암호화, 클라이언트에게 발급
- 클라이언트는 Token을 브라우저의 쿠키나 웹 스토리지에 저장한다.
- HTTP 요청 시 헤더에 토큰을 넣어 보낸다.
- 서버는 전달받은 요청메시지 헤더의 토큰의 시그니처를 서버가 들고 있는 secret key를 통해 Verification (복호화 후 조작 여부나 expired 확인) 한 뒤, 유저에게 권한 인가해줌.
구조
- Header 헤더
- 토큰 타입(JWT)과 해싱 알고리즘(SHA256 or RSA)을 지정.
- Payload 정보
- 토큰에 담을 정보(클레임)가 들어있음
- Signature 서명(Verification에 사용)
- 헤더의 인코딩 값과 페이로드의 인코딩 값을 합친 후 서버의 비밀 키로 해쉬
Reference)
https://velopert.com/2350
https://developer88.tistory.com/325
https://jins-dev.tistory.com/entry/Session-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EA%B3%BC-Token-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D