스프링부트, 리액트 http-only jwt 토큰 (with 쿠키) 설정방법

------------------------작성중--------------------------

jwt 를 발급하는 것은 쉽지만, 프론트와 소통하며 원활한 플로우를 이뤄내는 것은 정말 쉽지 않은 일이다. 그러나 우리 팀원들은 밤낮을 갈아가며 해내고 말았다. 이 과정이 너무 소중하고 내가 개발을 사랑한다는 확신을 주게 된 소중한 경험이라 공유하고 싶어 이렇게 글을 남긴다.

제가 직접 제작한 이미지들과 코드들이므로 불펌은 하지 말아주세요 :D

0) jwt 토큰 소통, 인증, 발급 방식

1) 로그인 시

실제 응답 결과 :
1) json response

    "success": true,
    "code": 0,
    "result": {
        "data": {
            "accessToken": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIzMDEiLCJpYXQiOjE2NDkxNjAyMjQsImV4cCI6MTY0OTE2MjAyNH0.2PUzUF4ECX3bZFRehI0V27ed_Yu3pd5_dyvdKjqKp3I",
            "refreshToken": "httponly",
            }
	 }

2) REFRESH TOKEN은 response header에 SET-COOKIE로 지정

  • set-cookie 옵션으로 클라이언트의 쿠키에 리프레시 토큰을 저장해주는 방식

2) 로그인 후 요청 보낼 때

1) 클라이언트 요청 보낼 때 (postman 예시)

  • Authorization 헤더에 Bearer abc... 를 넣는 형식으로 반드시 액세스 토큰을 보내줘야 한다.

  • 다만 액세스가 유효하지 않다면 클라이언트가 가지는 리프레쉬 토큰을 가지고 리프레시가 유효한 지 여부를 따진 다음에 다시 액세스를 발급해주던가 해야 하므로 해당 api로 이동해야 한다

3) 액세스 토큰을 리프레시 토큰을 통해 재발급

  • 리프레시 토큰은 쉽게 탈취당하지 않도록 http only 속성으로 쿠키에 저장되어 있어 js 브라우저나 타인이 쉽게 볼 수 없고 탈취가 어렵다

스프링부트

  • doFilter 메소드를 호출하는 곳

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response1 = (HttpServletResponse) response;
        HttpServletRequest request1 = (HttpServletRequest) request;

        response1.setHeader("Access-Control-Allow-Origin", "https://naughty-raman-7e7eb1.netlify.app");
        response1.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response1.setHeader("Access-Control-Max-Age", "3600");
        response1.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Origin,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
        response1.setHeader("Access-Control-Allow-Credentials",  "true");

        String token = extractToken(request);

        if(validateToken(token)) {
            // SecurityContext에 Authentication 객체 저장
            setAuthentication(token);
        }

        chain.doFilter(request, response1);
 }

주의사항

  • 응답.setHeader("Access-Control-Allow-Credentials", "true"); 을 설정하는 경우라면
  • 응답.setHeader("Access-Control-Allow-Origin", "cors허용할 사이트"); 에서 cors허용할 사이트를 특정해 지정해줘야 한다! "*"로 하면 안된다.

좋은 웹페이지 즐겨찾기