230629 JwtAuthenticationFilter

보트·2023년 6월 28일
0

Spring

목록 보기
10/27

JwtAuthenticationFilter

문제

로그인 성공 시 ApiResponseDto를 통해 성공 메세지와 상태 코드를 반환하고 싶었다.

하지만 Read-Only라는 오류 문구와 함께 실행되지 않았다.

    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) {
        String username = ((UserDetailsImpl) authResult.getPrincipal()).getUsername();

        // token 생성
        String token = jwtUtil.createToken(username);
        // header 에 바로 넣어줌
        response.addHeader(JwtUtil.AUTHORIZATION_HEADER, token);
    }

시도

return type 등을 바꿔보려고 했지만 그렇게 간단하게 수정할 수 없었다.

해결

content-type 을 application/json으로 지정
-> Jackson 라이브러리가 제공하는 objectMapper.writeValueAsString()을 사용해 객체를 JSON 문자로 변경
-> response.getWriter().write()을 사용해 단순 텍스트로 응답

protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException{

        log.info("로그인 성공 및 JWT 생성");
        String username = ((UserDetailsImpl) authResult.getPrincipal()).getUsername();
        UserRoleEnum role = ((UserDetailsImpl) authResult.getPrincipal()).getUser().getRole();

        // token 생성
        String token = jwtUtil.createToken(username, role);

        // header 에 바로 넣어줌
        response.addHeader(JwtUtil.AUTHORIZATION_HEADER, token);

        ApiResponseDto apiResponseDto = new ApiResponseDto("로그인 성공", 200);
        String json = new ObjectMapper().writeValueAsString(apiResponseDto);

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(json);

    }

알게된 점

Servlet Response 방식

  • HTTP Response
    : HTTP 응답코드 지정, 헤더 생성, 바디 생성, 옵션 제공(Content-Type, Cookie, Redirect,,)
		//응답코드 지정
        response.setStatus(HttpServletResponse.SC_OK);    //http 응답코드 200으로 적어도 되지만 이미 선언되어있는 상수를 사용하는게 의미 있는 값으로 사용할 수 있음.

        //헤더 생성
        //response.setHeader("Content=Type", "text/plain;charset=urf-8"); //응답하는 데이터의 타입
        response.setHeader("Cache=Control", "no-cache, no-store, must-revalidate"); //캐시를 저장하지 않게
        response.setHeader("Pragma", "no-cache");   //캐시를 저장하지 않게2
        response.setHeader("my-header", "hello");   //커스텀 헤더

        //header 옵션 
        content(response);
        cookie(response);
        //redirect(response);

        //바디 생성
        PrintWriter writer = response.getWriter();
        writer.write("ok");
  • HTML Response
    : 웹 프로젝트를 사용할 때 내부 통신의 경우 html 소스를 그대로 반환해야 하는 경우 사용
        //Content-Type: text/html; charset=utf-8
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        PrintWriter writer = response.getWriter();
        writer.println("<html>");
        writer.println("<body>");
        writer.println("    <div>hi 에이치 아이</div>");
        writer.println("</body>");
        writer.println("</html>");
  • JSON Response(api 방식)
    : Content-Type을 application/json으로 지정, class를 만들어 객체로 데이터 변환
    값을 세팅한 후 String으로 변환 후에 response에 담아서 내보내기
        ApiResponseDto apiResponseDto = new ApiResponseDto("로그인 성공", 200);
        String json = new ObjectMapper().writeValueAsString(apiResponseDto);

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(json);

(참고 : https://velog.io/@ililil9482/Servlet-response%EC%9D%91%EB%8B%B5)

JwtAuthenticationFilter

(extends UsernamePasswordAuthenticationFilter)
: 로그인, jwt 생성

UsernamePasswordAuthenticationFilter

: username, password 받음 > UsernamePasswordAuthenticationToken 생성 > AuthenticationManager를 통해 확인
: 그냥 사용하면 session 방식, jwt 방식 사용하려면 직접 구현

setFilterProcessUrl()

: 생성자 호출할 때 post 방식의 로그인 url 넣어 설정

JwtAuthorizationFilter

(extends OncePerRequestFilter)
: jwt 검증 및 인가

OncePerRequestFilter

: 메서드 매개변수로 HttpServeletRequest, HttpServeletResponse 받아올 수 있음

profile
일주일에 한 번

0개의 댓글