대표적인 토큰기반 인증중 하나인 JWT에 대해서 알아보자.
session방식에서는 서버에 민감한 정보를 저장하였다. 매 요청마다 데이터베이스를 살펴보는 것이 불편하여 이러한 부담을 덜기위해 클라이언트쪽에서 유저의 정보를 담을수있게 한 방법이다.
토큰은 유저정보를 암호화한 상태로 담기 때문에 XSS,CSRF 공격을 방어할 수 있다.
JWT 종류는 Access Token과 Refresh Token이 있다.
처음으로 인증을 받게 될때 access,refresh token 모두 받지만, 실제로 권한을 얻는데 사용하는 토큰은 access token이다.
access token만으로 권한을 얻지만 두가지 모두 사용하는 이유는 보안을 위해 access token에는 비교적 짧은 유효기간을 주어서 탈취되더라도 오랫동안 사용할 수 없게 만들 수 있다. 유효기간이 만료되면 refresh token을 사용하여 새로운 access token을 발급 받는다. (이때, 다시 로그인 할 필요가 없다.)
유효기간이 긴 refresh token을 탈취당한다면 상당히 위험하기 때문에 refresh token을 사용하지 않는곳도 많다고한다.
JWT 구조
1. Header
어떤 종류의 토큰인지, 어떤 알고리즘으로 암호화 할지가 적혀있다.
2. Payload
정보가 담겨있다. 접근가능한지에 대한 권한을 담을 수도 있고, 사용자의 유저이름등 필요한 데이터는 이곳에 담아 암호화 시킵니다. 암호화 될정보지만 민감한 정보는 되도록 담지 않는것이 좋다.
3. Signature
1,2번 모두 base64로 인코딩 되었다면 salt를 사용하여 암호화한다.
클라이언트가 아이디/비밀번호를 담아 로그인 요청을 보냄
서버에서 아이디/비밀번호가 일치하는지 확인하고, 토큰을 생성한뒤, 클라이언트로 보냄 (aceess,refresh 둘다)
여기서, 두종류의 토큰이 같은 정보를 담을 필요는 없다.
클라이언트에서 토큰을 저장한다.
저장위치는 react state, 로컬 스토리지, 쿠키등이 될수 있다.
클라이언트가 헤더에 토큰을 담아 서버로 보낸다.
서버는 해독하여 우리가 발급해준 토큰이 맞다면 요청을 처리하고, 응답한다.
1. statelessness & scalability (무상태성 & 확장성)
클라이언트가 토큰을 가지고 있으므로 서버에서 정보를 저장할 필요없이 클라이언트에서 보낸 토큰이 우리가 발급해준게 맞는지만 확인하면 된다.
2. 안정성
토큰은 암호화 되어있기 때문에 XSS,CSRF를 방어할 수 있다.
3. 어디서나 생성 가능
토큰을 생성한 곳에서 꼭 확인 절차를 받을 필요가 없다. 서버가 여러개이면 한곳에서 받은 토큰을 다른곳에도 확인을 받을 수 있다. 그래서 토큰 생성용 서버를 만들어 사용하는 곳도 있다.
4. 권한 부여에 용이
payload안에서 접근가능한 정보를 정할 수 있다.