SPACE RUMI

Hi, I am rumi. Let's Splattack!

[IT] 프로덕트 개발/기타

쿠키와 세션, JWT 토큰, 액세스토큰, 리프레시토큰 / Cookie, Session, JWT

스페이스RUMI 2022. 9. 3. 23:58
반응형

HTTP 프로토콜은 통신(Request, Response)이 끝나면 연결 상태를 유지하지 않는다. 따라서 서버는 누가 요청을 보냈는지, 유효한 사용자인지 매번 확인해야한다.

쿠키와 세션

쿠키는 로컬브라우저에 저장되는 key, value 쌍의 작은 기록 정보 파일이다. 세션ID를 담아 전달하는 도구라 생각하자.
유효시간을 명시 할 수 있고, 브라우저를 닫아도 로컬 브라우저에 저장된 클라이언트의 정보를 참조하기 때문에 인증이 유지된다.
Response Header에 Set-Cookie 속성을 사용하면 클라이언트에서 쿠키를 만들 수 있다.
사용자 인증정보를 클라이언트가 가지고 있으므로 보안에 취약하다.
쿠키와 세션을 이용하면 현재 몇명, 누가 로그인했는지를 판단할 수 있다.

 

1. 클라이언트가 웹사이트에 접속하여 서버에 요청(Request)을 한다.
2. 서버는 쿠키를 구워서 응답(Request)과 함께 보낸다.
3. 클라이언트는 요청시마다 세션ID를 쿠키에 담아 서버에 보낸다.
4. 서버는 요청을 받으면 받은 쿠키의 세션ID를 세션DB에 저장한다.
5. 서버는 클라이언트가 요청시 보내는 세션ID가 세션DB에 있는지 확인하여 유효한 사용자인지 판단한다.

 

JWT (JSON Web Token)

JWT는 Header, Payload, Signature 3 부분으로 이루어진다.
JWT를 쓰면 사용자 인증시 세션DB를 가지고 있지 않아도 된다. 
그럼 개인정보와 같은 이 JWT는 어디에 저장해야할까?

1. 로컬스토리지
CSRF공격에는 안전하나 XSS에 취약하다.

2. 쿠키
로컬스토리지보다는 XSS공격으로부터 안전하지만, CSRF에 취약하다.

XSS 공격 : 스크립트 심어서 조작하는 공격
CSRF 공격: 네트워크 패킷캡쳐를 통한 공격

 

액세스토큰과 리프레시토큰

https + httpOnly 쿠키로 토큰을 저장하면, 프론트에서 접근이 불가능하다.
api 요청 시에도 별도로 헤더에 토큰을 안 태워보내도 자동으로 붙어서 가기 때문에, 액세스토큰에 httpOnly를 붙이는것이 더 편하다.

액세스 토큰은 토큰 자체만 보고 암호화 풀어서 인증을 완료한다.
리프레시 토큰은 레디스나 DB에 저장된 리프레시 토큰과 비교를 하는 검증과정을 거친다. 

액세스토큰을 헤더에 태워 보냈는데, 토큰이 만료되었다면 401 에러나 에러코드를 내려줄거다.
그러면 리프레시 갱신 요청을 보내서(액세스토큰+리프레시토큰) 토큰을 갱신하면 된다.


요약)

1. 로그인 요청, 백엔드가 AccessToken, RefreshToken을 보낸다.
(리프레시토큰에 httpOnly 붙인다) 이때 백엔드는 레디스나 DB에 리프레시토큰을 별도로 저장한다.
2. 프론트는 AccessToken을 암호화하여 로컬스토리지나 프라이빗 변수에 저장한다.
3. api 요청 시마다 헤더에 AccessToken을 담아 요청한다.
4. 만약 AccessToken이 만료되었다면, 401에러나 에러코드를 내려줄것이다.
5. 이때 리프레시 갱신 요청을 보낸다 (AccessToken + RefreshToken)
리프레시토큰에는 httpOnly로 쿠키에 담겨있을테니 자동으로 같이 갈것이므로, 프론트가 해 줄 일은 딱히 없다.
백엔드는 받은 쿠키의 리프레시토큰과 저장해둔 리프레시토큰과 비교하여 검증과정을 거친다.

 

✧ Access Token && Refresh Token을 사용하자.

스크립트 언어에 의해 쿠키 수정을 막아주는 HttpOnly 플래그를 붙여준다. 이러면 JS 환경에서 쿠키수정이 불가능하다(읽기, 쓰기 불가능), 또한 브라우저 새로고침시마다 새로운 accessToken을 발급받는다. 이 accessToken은 js private variable에 저장한다.

AccessToken의 유효기간을 짧게 설정하고, RefreshToken의 유효기간을 길게 설정하여, AccessToken이 탈취당하더라도 '진짜' 사용자는 RefreshToken을 발급받아 유효성을 인증할수있도록 한다.

 

참고 자료 : 니콜라스 유튜브 Cookie Session, is-a-refresh-token-really-necessary-when-using-jwt-token-authentication 

반응형