로그인 방식과 JWT

오다현·2025년 12월 7일
post-thumbnail

일반 로그인 vs 소셜 로그인

(프론트 기준)

일반 로그인

  1. 회원가입 버튼 클릭
  2. 아이디 중복 체크
  3. 비밀번호 입력
  4. 서버에 회원가입 요청 (POST)
  5. 서버가 DB에 사용자 정보 저장
  6. 프론트에서 아이디 + 비밀번호로 로그인 요청
  7. 로그인 성공 시 백엔드가 JWT 발급

소셜 로그인 (OAuth2 + JWT 예시)

  1. (소셜) 로그인 버튼 클릭
  2. 소셜 로그인(인가 서버) 페이지로 이동
  3. 사용자 로그인 성공
  4. 소셜 서버(인가 서버) → 백엔드에게 인증 코드(code) 전달
https://~/~/~/?code=ABC123
  1. 백엔드는 이 인증 코드를 이용해 소셜 서버(인가 서버)에 Access Token 요청
  2. 백엔드는 받은 Access Token으로 (자원서버)에 사용자 정보 요청

이렇게 사용자 정보는 백엔드가 직접 소셜 서버(자원 서버)에 요청해서 받아온다.
이후 백엔드는 사용자 정보를 보고 신규 회원이면 DB 저장, 기존 회원이면 로그인 처리 등을 수행한다.

  1. 마지막으로 백엔드는 우리 서비스에서 사용할 JWT를 생성해 프론트에게 전달한다.
localStorage.setItem("accessToken", accessToken);

정리하면, 소셜 로그인은 백엔드가인가 서버와 자원 서버와의 통신을 모두 처리한 뒤, 최종적으로 우리 서비스용 JWT만 프론트에게 넘겨주는 방식이다.

(소셜 로그인 자체가 반드시 JWT를 써야 하는 건 아니고, 여기서는 소셜 로그인 + JWT를 함께 쓰는 구조를 예시로 든 것이다.)

JWT란?

JWT는 백엔드가 이 사용자는 인증된 사용자다라는 정보를 담아서 프론트에게 전달하는 토큰이다. 보통 Access Token을 JWT 형태로 만드는 경우가 많다.

JWT는 항상 header.payload.signature 형태의 문자열이고, 안에는 예를 들어

  • 유저 ID
  • 권한
  • 토큰 만료 시간
    같은 정보가 들어있다.

프론트는 이 JWT을 적절한 장소에 저장해두었다가 모든 API 요청마다 Authorization 헤더에 붙인다.

Access Token vs Refresh Token

Access Token

API 요청할 때 Authorization 헤더에 넣는 토큰으로, 유효기간이 짧고 (5~30분) 노출되면 위험하지만 유효기간이 짧아서 피해가 제한적이다.
프론트에서 보통 LocalStorage, SessionStorage, 메모리에 저장한다.

Refresh Token

Access Token이 만료되었을 때 새로운 Access Token을 발급받는 마스터 키로 유효기간이 길어서 탈취되면 계정 전체가 위험해진다.

동작 흐름은 이렇다.

Access Token 만료 -> 요청시 401 Unauthorized -> 백엔드는 브라우저에 남아 있던 Refresh Token을 보고 Access 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보다 더 안전한 방식이 될 수 있다.

Refresh Token을 localStorage에 저장하면 어떻게 될까?

No.

localStorage는 JS로 접근 가능하고 xss 공격에 취약하기 때문에 공격자에 의해서 리프레시토큰 탈취 , 엑세스토큰 무한 재발급 등 심각한 문제가 발생한다.

그래서 Refresh Token은 반드시 HttpOnly + Secure 쿠키로만 저장한다.

  • HttpOnly → JS에서 접근 불가(XSS 방어)
  • Secure → HTTPS 전용 전송(중간 탈취 방어)
profile
프론트엔드 개발자 지망생

0개의 댓글