Are sessions needed for python-social-auth

前端 未结 2 1926
慢半拍i
慢半拍i 2021-01-31 05:48

I\'m building a django app with an API backend(built with DRF) and angularjs client. My goal is to completely decouple the server and client using JWT in place of sessions. I\'m

2条回答
  •  佛祖请我去吃肉
    2021-01-31 05:54

    No, you do not need to use sessions(standard Django login system) with python-social-auth. What you need to make JWT and PSA work together is DRF.

    Here's my solution:

    I used standard PSA's url for making request too social /login/(?P[^/]+)/$, changed url in urls.py to match redirect from Facebook/Twitter to my own.

    url(r'^complete/(?P[^/]+)/$', views.SocialAuthViewComplete.as_view()),
    

    The point of using API is to have access to user data in request that PSA is doing. DRF allow you to do it if you have JWT authentication in DEFAULT_AUTHENTICATION_CLASSES

    REST_FRAMEWORK = {
              'DEFAULT_AUTHENTICATION_CLASSES': (
                  'rest_framework.authentication.SessionAuthentication',
                  'rest_framework.authentication.TokenAuthentication',
                  'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),}
    

    In views.py

    from social.apps.django_app.views import complete
    
    class SocialAuthViewComplete(APIView):
        permission_classes = ()
    
        def post(self, request, backend, *args, **kwargs):
            try:
                #Wrap up  PSA's `complete` method.    
                authentication = complete(request, backend, *args, **kwargs)
            except Exception, e:
                exc = {
                    'error': str(e)
                }
                return Response(exc, status=status.HTTP_400_BAD_REQUEST)
            return Response({'data': authentication}, status=status.HTTP_202_ACCEPTED)
    

    Then I modified the do_complete method in PSA:

    def do_complete(backend, login, user=None, redirect_name='next',
                    *args, **kwargs):
        # pop redirect value before the session is trashed on login()
        data = backend.strategy.request_data()
        redirect_value = backend.strategy.session_get(redirect_name, '') or \
                         data.get(redirect_name, '')
    
        is_authenticated = user_is_authenticated(user)
        user = is_authenticated and user or None
    
        partial = partial_pipeline_data(backend, user, *args, **kwargs)
        if partial:
            xargs, xkwargs = partial
            user = backend.continue_pipeline(*xargs, **xkwargs)
        else:
            user = backend.complete(user=user, *args, **kwargs)
    
        user_model = backend.strategy.storage.user.user_model()
        if user and not isinstance(user, user_model):
            return user
    
        if is_authenticated:
            if not user:
                information =  'setting_url(backend, redirect_value, LOGIN_REDIRECT_URL'
            else:
                information =  'setting_url(backend, redirect_value, NEW_ASSOCIATION_REDIRECT_URL,LOGIN_REDIRECT_URL'
        elif user:
            # Get the JWT payload for the user.
            payload = jwt_payload_handler(user)
    
            if user_is_active(user):
                is_new = getattr(user, 'is_new', False)
                if is_new:
                    information = 'setting_url(backend, NEW_USER_REDIRECT_URL, redirect_value, LOGIN_REDIRECT_URL'
                else:
                    information = 'setting_url(backend, redirect_value, LOGIN_REDIRECT_URL'
            else:
                return Response({
                            'status': 'Unauthorized',
                            'message': 'The user account is disabled.'
                        }, status=status.HTTP_401_UNAUTHORIZED)
        else:
            information = 'setting_url(backend, LOGIN_ERROR_URL, LOGIN_URL'
    
    
        return { 'an information i may use in future': information,
                 'token': jwt_encode_handler(payload) # Create the response object with the JWT payload.
        }
    

    I tried pipelines and user association and it works correctly. Also you always can modify another method from PSA, if you need it to works with JWT.

提交回复
热议问题