[Django][Web]Djangoのsimple-jwtでログイン機能を実現(2)


simple-jwtの2番目!
今日は、受信したaccess、refreshタグに基づいてユーザーを識別する方法について説明します.
つまり、ログインしたと仮定すると、サーバはタグに基づいてユーザーの情報を識別します.
まず、私のコードは次のとおりです.
        try:
            access_token = request.COOKIES['access_token']
            payload = jwt.decode(access_token, env('DJANGO_SECRET_KEY'), algorithms=['HS256'])
            pk = payload.get('user_id')
            user = get_user(pk)
            serializer = UserSeriallizer(user)
            response = Response(
                serializer.data,
                status=status.HTTP_200_OK
            )
            response.set_cookie('access_token', access_token)
            response.set_cookie('refresh_token', request.COOKIES['refresh_token'])
            return response

        # 토큰 만료시 토큰 갱신
        except(jwt.exceptions.ExpiredSignatureError):
            try:
                # access 토큰 만료시
                serializer = TokenRefreshSerializer(data={'refresh': request.COOKIES.get('refresh_token', None)})

                if serializer.is_valid(raise_exception=True):
                    access_token = serializer.validated_data['access']
                    refresh_token = request.COOKIES.get('refresh_token', None)
                    payload = jwt.decode(access_token, env('DJANGO_SECRET_KEY'), algorithms=['HS256'])
                    pk = payload.get('user_id')
                    user = get_user(pk)
                    serializer = UserSeriallizer(instance=user)
                    response = Response(serializer.data, status=status.HTTP_200_OK)
                    response.set_cookie('access_token', access_token)
                    response.set_cookie('refresh_token', refresh_token)
                    return response
            except(rest_framework_simplejwt.exceptions.TokenError): # refresh 토큰까지 만료 시
                return Response({"message": "로그인이 만료되었습니다."}, status=status.HTTP_200_OK)

            raise jwt.exceptions.InvalidTokenError

        except(jwt.exceptions.InvalidTokenError): # 토큰 invalid 인 모든 경우
            return Response({"message": "로그인이 만료되었습니다."}, status=status.HTTP_200_OK)
分けると3つのケースがあります
  • accessトークンが有効である場合、->accessトークンを使用してユーザ情報
  • を識別する.
  • accessトークンが期限切れになった場合->refreshトークンを使用して新しいaccessトークンを発行する+このトークンを使用してユーザ情報を識別する
  • .
  • refreshトークン期限切れ+その他のトークンエラーの例外->ログイン期限切れ
  • このように分けて論理を編んだ.
    ここで説明する組み込み関数はTokenRefreshSerializerです.
    これは2つ目の場合に使用されます.
    アクセストークンが期限切れになった場合、refreshトークンを使用して新しいアクセストークンを発行するシーケンス化器!
    これには、次のものが含まれます.
    class TokenRefreshSerializer(serializers.Serializer):
        refresh = serializers.CharField()
        access = serializers.CharField(read_only=True)
    
        def validate(self, attrs):
            refresh = RefreshToken(attrs['refresh'])
    
            data = {'access': str(refresh.access_token)}
    
            if api_settings.ROTATE_REFRESH_TOKENS:
                if api_settings.BLACKLIST_AFTER_ROTATION:
                    try:
                        # Attempt to blacklist the given refresh token
                        refresh.blacklist()
                    except AttributeError:
                        # If blacklist app not installed, `blacklist` method will
                        # not be present
                        pass
    
                refresh.set_jti()
                refresh.set_exp()
                refresh.set_iat()
    
                data['refresh'] = str(refresh)
    
            return data
    すなわち、受信されたrefreshトークンに基づいてrefreshが行われる.access token.
    新しいaccessトークンが発行され、返されます!
    したがって、この操作を実行すると、
    access_token = serializer.validated_data['access']
    新しいaccess tokenを取得するために実行します!
    このアクセス値をTokenRefreshSerializerから取得した場合.
    この間シーケンサdataで値を取得できるので、ずっとこのように書いて、結果はずっとエラーが発生しました.
    組み込み関数を引き続き表示し、一つ一つチェックし、validate dataのみを使用してaccessトークンの値を取得できます.ううう
    ここですね.データメソッドはサポートされていないようです.
    アクセストークン値はvalidated dataのみで取得できます.
    もう一つの問題はまだ解決されていない.
    この操作を実行すると、refresh値はdata['refresh']=str(refresh)にも含まれます.
    このrefresh値は取れない...?
    アクセストークンはインポートされましたが、この値はインポートされません.
    もちろん、ここではaccessトークンの値を更新するだけですが、ちょっと気分が悪いです.
    TokenRefreshSerializerのrefresh tokenの値が何か知っていたらコメントで教えてください
    とにかく.こうして論理を完成させた
    このようにユーザ情報を認識するたびに使用するこの部分は、いっそ関数として取り、ディレクトリを個別に作成し、ファイルを作成して個別に保存し、必要に応じてインポートしてから使用するとよい.
    私も別に取り出して、必要なときにコールで書きます!!
    次に、djangoタグ機能を提供するモジュールであるtaggitについて説明します.
    私达のサービスの中でラベルの机能があって、ちょうどManytomyで実现したいと思って、とても良いモジュールを発见して、ほほほ、私はできるだけ早く开いてみんなに教えます!😍