토큰이란 인증 방식 중 하나로 유저 정보를 암호화하여 클라이언트에 보관하는 방식이다.
토큰 기반 인증 중 가장 대표적인 JWT(JSON Web Token)에 대해서 알아보자.
JWT는 보통 다음과 같이 두 가지 종류의 토큰을 이용해 인증을 구현한다.
엑세스 토큰은 보호된 정보들(유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용한다.
클라이언트가 처음 인증을 받게 될 때(로그인 시) 엑세스 토큰, 리프레시 토큰 두가지를 다 받지만, 실제로 권한을 얻는 데 사용하는 토큰은 엑세스 토큰이다.
엑세스 토큰의 유효기간이 만료되었을때 리프레시 토큰을 이용하여 엑세스 토큰의 재발급을 요청한다.
서버는 DB에 저장된 리프레시 토큰과 비교하여 유효한 경우 새로운 액세스 토큰을 발급하고, 만료된 경우 사용자에게 로그인을 요구한다.
어떤 종류의 토큰인지, 어떤 알고리즘으로 암호화 할지가 적혀있다. JSON 형태로 정보가 담겨있다.
{
"alg" : "HS256",
"typ" : "JWT",
}
어떤 정보에 접근 가능한지에 대한 권한 또는 유저의 이름과 같은 개인정보 등을 담을 수 있다.
시그니처를 통해 유효성이 검증될 정보이긴 하지만, 너무 민감한 정보는 담지 않는 것이 좋다.
디코딩이 쉬운 base64 방식으로 인코딩되기 때문이다.
{
"sub" : "someInformation",
"name" : "phillip",
"iat" : 151623391
}
base64로 인코딩된 Header, Payload 부분이 완성 되었다면, Signature는 이를 서버의 비밀 키(암호화에 추가할 salt)와 헤더에서 지정한 알고리즘을 사용하여 암호화한다.
따라서 누군가 권한을 속이기 위해 Payload를 변조하여 base64로 인코딩하더라도 원본 Payload로 암호화한 시그니처 값과 다르기 때문에 서버가 해당 토큰이 변조되었음을 확인할 수 있다.
클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보낸다.
아이디/비밀번호가 일치하는지 확인하고, 클라이언트에게 보낼 암호화된 토큰을 생성한다.
서버가 클라이언트에게 토큰을 보내주면, 클라이언트는 토큰을 저장한다.
클라이언트가 HTTP 헤더(Authorization 헤더) 또는 쿠키에 토큰을 담아 보낸다. 쿠키에는 리프레시 토큰을 헤더 또는 바디에는 액세스 토큰을 담는 등 다양한 방법으로 구현할 수 있다.
서버는 토큰을 해독하여 발급한 토큰과 일치하면, 클라이언트의 요청을 처리한 후 응답을 보내준다.
무상태성, 확장성
안전하다
어디서나 생성 가능하다.
권한 부여에 용이하다.