SpringBoot/기능구현

[인가 기능] - Jwt 토큰 활용

공부 기록장 2025. 1. 7. 22:17

▶ 실제 토큰 발급 흐름 

  1. 사용자가 로그인하면 서버에서 Access Token과 Refresh Token을 발급한다.
    • Access Token은 HTTP 응답 헤더로 반환.
    • Refresh Token은 HttpOnly 쿠키에 저장.
  2. 클라이언트는 API 호출 시 Access Token을 로컬 변수에 임시 저장하고 요청에 사용한다.
  3. Access Token이 만료되면, 클라이언트는 Refresh Token을 기반으로 서버에 새 Access Token을 요청한다.
  4. 서버에서 Refresh Token 을 검증한 후  Access Token과 Refresh Token을 재발급한다.
  5. 재발급에 사용한 Refresh Token을 쿠키에서 삭제하고 새로 발급 받은 Refresh Token을 저장한다.

1. 토큰 발급

백엔드 : 로그인 성공 시 accessToken, refreshToken 을 발급하여

accessToken은 HTTP 응답의 authentication header 에 넣고

refreshToken은 httpOnly, secure, SameSite 옵션을 적용한 쿠키에 저장한다.

프론트엔드 : accessToken을 로컬 변수에 저장한다.

 

 

2. 토큰 재발급

프론트엔드 : 클라이언트가 API 요청을 보낼 때 서버에서 401 Unauthorized 응답을 받으면 accessToken 재발급 요청

▶ 백엔드 : refreshToken을 검증하여 accessToken과 refreshToken 을 재발급한다.

▶ 백엔드 : 기존 refreshToken을 쿠키에서 삭제하고 새로 발급받은 refreshToken을 쿠키에 저장한다.

 

 

 

3. 토큰 인증

 프론트엔드 : API 요청 Header에 accessToken 을 추가한다.

▶ 백엔드 : API 요청 Header 에 있는 accessToken을 검사한다. 

▶ 백엔드 : 문제가 없는 경우 페이지 접근을 허용한다.

 

@PostMapping
    public ResponseEntity<LoginResponse> login(@Valid @RequestBody LoginRequest request, HttpServletResponse response){
        LoginResponse loginResponse = userService.login(request);
        response.setHeader("Authorization", "Bearer "+loginResponse.refreshToken());
        setRefreshTokenCookie(response, loginResponse.refreshToken());
        return ResponseEntity.ok()
                .body(loginResponse);
    }

 

LoginResponse loginResponse = userService.login(request) : 로그인 성공 시 LoginResponse 객체를 생성하여 반환받음

response.setHeader : HTTP 응답 헤더에 Authorization 헤더를 추가한다.

setRefreshTokenCookie : 로그인 시 발급된 refreshToken 을 HttpOnly 쿠키에 저장하기 위해 호출하는 메소드

 

 

 

 

private void setRefreshTokenCookie(HttpServletResponse response, String refreshToken){
        Cookie cookie = new Cookie("refreshToken", refreshToken);
        cookie.setHttpOnly(true);      //js 에서 쿠키에 접근할 수 없도록 함(xss 공격 방지)
        cookie.setSecure(true);        //https 연결에서만 쿠키 전송
        cookie.setPath("/");           //쿠키가 적용될 경로
        cookie.setMaxAge(60*60*24*30); //쿠키 유효 기간(30일)
        cookie.setAttribute("SameSite", "Strict");
        //외부사이트에서 요청할 경우 쿠키를 전송하지 않도록 설정 (CSRF 공격 방지)

        response.addCookie(cookie);
    }