(프론트 기준)
https://~/~/~/?code=ABC123
이렇게 사용자 정보는 백엔드가 직접 소셜 서버(자원 서버)에 요청해서 받아온다.
이후 백엔드는 사용자 정보를 보고 신규 회원이면 DB 저장, 기존 회원이면 로그인 처리 등을 수행한다.
localStorage.setItem("accessToken", accessToken);
정리하면, 소셜 로그인은 백엔드가인가 서버와 자원 서버와의 통신을 모두 처리한 뒤, 최종적으로 우리 서비스용 JWT만 프론트에게 넘겨주는 방식이다.
(소셜 로그인 자체가 반드시 JWT를 써야 하는 건 아니고, 여기서는 소셜 로그인 + JWT를 함께 쓰는 구조를 예시로 든 것이다.)
JWT는 백엔드가 이 사용자는 인증된 사용자다라는 정보를 담아서 프론트에게 전달하는 토큰이다. 보통 Access Token을 JWT 형태로 만드는 경우가 많다.
JWT는 항상 header.payload.signature 형태의 문자열이고, 안에는 예를 들어
프론트는 이 JWT을 적절한 장소에 저장해두었다가 모든 API 요청마다 Authorization 헤더에 붙인다.
API 요청할 때 Authorization 헤더에 넣는 토큰으로, 유효기간이 짧고 (5~30분) 노출되면 위험하지만 유효기간이 짧아서 피해가 제한적이다.
프론트에서 보통 LocalStorage, SessionStorage, 메모리에 저장한다.
Access Token이 만료되었을 때 새로운 Access Token을 발급받는 마스터 키로 유효기간이 길어서 탈취되면 계정 전체가 위험해진다.
동작 흐름은 이렇다.
Access Token 만료 -> 요청시 401 Unauthorized -> 백엔드는 브라우저에 남아 있던 Refresh Token을 보고 Access Token 재발급 -> 프론트는 새 Access Token으로 다시 요청
LocalStorage
적용하기 쉬움
새로고침해도 유지됨
XSS에 취약
SessionStorage
브라우저 탭 닫으면 삭제
XSS에 취약
메모리
JS 변수에만 존재
XSS에 상대적으로 안전
새로고침시 초기화됨
그래서 많이 쓰는 방법은
Access Token → 메모리(또는 LocalStorage)
Refresh Token → HttpOnly 쿠키 이다.
메모리는 페이지가 새로고침되면 초기화되기 때문에 Access Token은 날아가지만 Refresh Token이 HttpOnly 쿠키에 남아 있으므로, 새로고침 시 자동으로 새로운 Access Token을 받아오면 된다. 오히려 XSS 위험을 줄인다는 점에서 LocalStorage보다 더 안전한 방식이 될 수 있다.
No.
localStorage는 JS로 접근 가능하고 xss 공격에 취약하기 때문에 공격자에 의해서 리프레시토큰 탈취 , 엑세스토큰 무한 재발급 등 심각한 문제가 발생한다.
그래서 Refresh Token은 반드시 HttpOnly + Secure 쿠키로만 저장한다.