본문 바로가기

회고록(TIL&WIL)

TIL 2022.11.30 simpleJWT 커스텀 및 spring에서 decode

simpleJWT 커스텀

JWT 로그인의 경우는 django 에서 지원하는 simple JWT 를 이용해서 구현을 했는데 payload 내에 email claim을 추가하고 로그인 시 is_seller의 값을 받아 판매자와 소비자를 구분하여 인증할 수 있도록 진행하기 위해서 커스텀으로 LoginUserAPIView 를 따로 생성하여 JWT 토큰을 생성하도록 구현하였다.

# user/login
class LoginUserAPIView(APIView):
    
    def post(self, request):
        serializer = LoginUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        data = serializer.validated_data # Fetch the data form serializer

        user = authenticate(email=data['email'], password=data['password']) # check for email and password
        if not user or user.is_seller != data['is_seller']: # check for phone
            raise serializers.ValidationError({'detail':'지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다'})

        # Generate Token
        refresh = RefreshToken.for_user(user)

        # add payload here!!
        refresh['email'] = data['email']

        return Response(
            {
                'access': str(refresh.access_token),
                'refresh': str(refresh)
            }
            , status=status.HTTP_200_OK
            )

access 토큰은 refresh토큰을 기준으로 생성되기 때문에 최초의 생성할 때 refresh 토큰에 추가할 데이터들을 추가하면 access 토큰에도 자연스럽게 claim이 추가 된다. 이를 토대로 다른 api 호출 시에도 토큰 내에서 id값과 email값을 조회할 수 있도록 설정하였다.


Spring 에서의 받아온 JWT Decode

public ResponseEntity<?> save(@RequestBody Payment params, HttpServletRequest request) throws JsonProcessingException {
        // header 에 받아온 JWT 토큰 Decode를 통한 접속한 유저의 email, user_id 값 가져오기
        String authToken = request.getHeader(HttpHeaders.AUTHORIZATION);
        String[] chunks = authToken.split("\\.");
        Base64.Decoder decoder = Base64.getUrlDecoder();
        String payload = new String(decoder.decode(chunks[1]));
        JSONObject jObject = new JSONObject(payload);
        String user_email = jObject.getString("email");
        Long user_id = jObject.getLong("user_id");
        params.setConsumerId(user_id);

HttpServletRequest 클래스를 이용하여 requset의 내용들을 받아와서

getHeader함수를 이용하여 Authorization 에 담아온 JWT 토큰을  가져와  . 기준으로 나눠져있는 JWT 토큰의 특성을 이용해서 payload 부분에 저장되어있는 claim 들을 불러와서 해당 id 값을 consumer_id로 줌으로써 get 요청 시 파라미터에 id 값을 직접 입력하는게 아닌 로그인 인증이 완료된 JWT 토큰을  이용하여 사용자의 정보를 가져올 수 있도록 했다.