Home > OS >  JWT auth using python-social-auth and django-rest-framework
JWT auth using python-social-auth and django-rest-framework

Time:07-14

I'm trying to convert a snippet of code that I found (using python-social-auth) to make it handle JWT authentication instead of simple token authentification.

Here is the code:

@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
@psa()
def oauth_exchange_token_view(request, backend):
    serializer = SocialAccessTokenSerializer(data=request.data)
    if serializer.is_valid(raise_exception=True):
        # set up non-field errors key
        try:
            nfe = "non_field_errors"
        except AttributeError:
            nfe = 'non_field_errors'

        try:
            # this line, plus the psa decorator above, are all that's necessary to
            # get and populate a user object for any properly enabled/configured backend
            # which python-social-auth can handle.
            user = request.backend.do_auth(serializer.validated_data['access_token'])
        except HTTPError as e:
            # An HTTPError bubbled up from the request to the social auth provider.
            # This happens, at least in Google's case, every time you send a malformed
            # or incorrect access key.
            return Response(
                {'errors': {
                    'token': 'Invalid token',
                    'detail': str(e),
                }},
                status=status.HTTP_400_BAD_REQUEST,
            )

        if user:
            if user.is_active:
                token, _ = Token.objects.get_or_create(user=user)
                return Response({'access': token.key})
            else:
                return Response(
                    {'errors': {nfe: 'This user account is inactive'}},
                    status=status.HTTP_400_BAD_REQUEST,
                )
        else:
            return Response(
                {'errors': {nfe: "Authentication Failed"}},
                status=status.HTTP_400_BAD_REQUEST,

As you can see in the code above, the token is returned like this:

token, _ = Token.objects.get_or_create(user=user)
return Response({'access': token.key})

But I would like it to return a JWT using djangorestframework-simplejwt instead.

CodePudding user response:

Finally found a solution:

from rest_framework_simplejwt.tokens import RefreshToken
# ...

@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
def register_view(request):
    # ...
        if user:
            if user.is_active:
                refresh = RefreshToken.for_user(user)
                res = {
                    'refresh': str(refresh),
                    'access': str(refresh.access_token),
                }
                return Response(res)
        # ...

CodePudding user response:

You don't need to write your views for simplejwt. Just go step-by-step in documentation. For most use cases "getting started" configure for simplejwt is enough.

  • Related