Web

Session vs Token(JWT)

superbono 2021. 7. 9. 17:34

* 인증(Authentication) vs 인가(Authorization)

https://dev.to/caffiendkitten/authentication-vs-authorization-25lc

인증(Authentication)

쉽게 말해서 로그인 내가 이 사이트에 회원가입한(데이터베이스에 내 정보가 저장되어 있는) 사용자임을 아이디와 패스워드 등을 통해서 인증을 받는 것

인가(Authorization)

인증(로그인)한 사용자가 서비스의 여러 기능을 사용할 때 서버가 이 사용자가 인증을 받은 사용자라는 것을 알아보고 허가를 해주는 것

 

 

* 인가(Authorization)를 어떻게 처리할 것인가?

네이버와 다음 같은 대규모 서비스를 생각해보자. 어떤 사람은 로그인 하지 않은 채로 뉴스를 읽고 어떤 사람은 로그인한 상태에서 메일을 보낸다. 매 초마다 수천, 수만개의 요청이 서버로 날아든다. 이 요청들 중 어떤 것은 로그인하지 않은 사용자이고 어떤 것은 로그인이 필요한 서비스의 요청인데, 서버는 어떻게 요청하는 클라이언트가 인증을 받은 것인지를 구분할 수 있을까?

 

 

* 세션 (Session)

인증을 받은 사용자의 정보를 세션으로 만들어서 서비스가 돌아가고 있는 서버에 저장을 한다. 브라우저는 세션 아이디 파일(쿠키)을 만들어 브라우저에 저장을 하고 다음 사이트에 요청을 보낼 때마다 이 쿠키를 같이 보낸다. 그러면 이제 세션 아이디와 저장되어 있는 세션이 있는지 검색하여서 있으면 허용해주고 없으면 거부한다. 이 Session ID를 사용해서 어떤 사용자가 서버에 지속적으로 로그인 되어있는 상태를 '세션'이라고 한다. 시간에 따라 바뀌는 상태값을 가지므로 stateful하다.

이 때 세션을 서버의 메모리/하드디스크/데이터베이스 등에 저장을 하는데, 당연히 메모리가 가장 빠르게 접근 가능하다. 그러나 메모리의 휘발 가능하다는 특성 때문에 에러가 발생하여 서버를 재부팅하여야 할 경우 메모리에 저장된 데이터는 전부 날아가고 인증받았던 사용자들은 다시 재인증 받아야 한다. (로그인 풀려서 다시 재로그인 해야된다는 소리)

 

 

* 토큰(Token) 방식인 JWT

사용자가 로그인을 하면 토큰을 발행하여 클라이언트에게 줘버린다. 서버는 토큰을 기억하고 있지 않는다! 시간에 따라서 상태값이 변하지 않아서 stateless하다는 성질을 갖는다. 인코딩 또는 암호화된 3가지 데이터를 이어붙인 것이다. 마침표로 끊어져서 세 부분으로 나뉘는데 header, payload, verify signature이다.

header 

헤더를 디코딩하면 type, 토큰의 타입인데 JWT가 항상 들어간다(고정 값) alg(algorithm) verify signature를 만드는데 지정되는 암호화 알고리즘(hash)이 지정된다. header와 payload, '서버에 감춰놓은 비밀 값' 이 셋을 이 암호화 알고리즘에 넣고 돌리면 signature 값이 나온다. 

paylod

디코딩해보면 json 형식으로 여러 정보들이 들어있다. 토큰의 유효 기간, 토큰을 가지고 있는 사용자가 접근 가능한 서비스 내용, 토큰을 누가 누구에게 발행했는지 등을 담을 수 있다. 토큰에 담긴 사용자 정보를 claim이라고 한다. 그러니까 사용자가 로그인을 하고 나면 받는 토큰에 정보들이 클레임이라는 이름으로 실려온다. 이후 사용자는 서버에 요청할 때마다 토큰을 보내고, 사용자가 보내는 토큰에 이런 정보들이 들어있으면 디코딩하여 이 사용자에 대한 정보를 서버는 알 수 있다. 

verify signature

header와 payload, '서버에 감춰놓은 비밀 값' 이 셋을 이 암호화 알고리즘에 넣고 돌린 값.

 

 

서버는 요청에 토큰 값이 들어오면 header와 payload의 값을 '서버에 감춰놓은 비밀 키' 와 함께 돌려봐서 계산한 결과값이 verify signature와 같은지 확인한다. -> 따라서 서버는 인증받은 사용자 정보를 기억할 필요 없이 '서버에 감춰놓은 비밀 키'만 가지고 있으면 header와 payload, 비밀 키를 가지고 해싱해서 verify signature와 같은지 비교하기만 하면 됨

 

 

 

'Web' 카테고리의 다른 글

HTTPS(HyperText Transfer Protocol Secure)  (0) 2021.07.25
Get과 Post의 차이점  (0) 2021.07.23
CORS(Cross-Origin Resource Sharing)  (0) 2021.05.20
SPA(Single Page Application)  (0) 2021.05.19
MVC vs MVVM  (0) 2021.05.12