Search code examples
djangodjango-rest-frameworkdjango-authentication

How to change response format of Django auth login api


I am currently using Django-rest-framework-social-oauth2 and it's login token creation endpoint, which on success, responds with the following data:

{
  "access_token": "************",
  "token_type": "Bearer",
  "expires_in": 36000,
  "refresh_token": "************",
  "scope": "read write"
}

But I want to change the format and wrap the data in that format:

{
  "status" : true,
  "data" :{
      "access_token": "************",
      "token_type": "Bearer",
      "expires_in": 36000,
      "refresh_token": "************",
      "scope": "read write"
    }
}

I read the Django documentation and tried extending the library view but no changes are showing up

from rest_framework_social_oauth2.views import TokenView 

    @api_view(('POST'))
    def post(self, request, *args, **kwargs):
        # Use the rest framework `.data` to fake the post body of the django request.
        request._request.POST = request._request.POST.copy()
        for key, value in request.data.items():
            request._request.POST[key] = value

        url, headers, body, status = self.create_token_response(request._request)
        response = Response(data=json.loads(body), status=status)

        for k, v in headers.items():
            response[k] = v
        return response

Solution

  • I would suggest to create a class based view and extend DRF-social-oauth2's TokenView which has a method post to create the token:

    1. views.py:

      from rest_framework_social_oauth2.views import TokenView
      
      class MyTokenView(TokenView):
      
          def post(self, request, *args, **kwargs):
              response = super(MyTokenView, self).post(request, *args, **kwargs)
              return Response({
                  'status': Your_Status,
                  'data': response.data,
              }, status=response.status_code)
      

      The .super method will create the desired token and then you can manipulate the response given as shown (and with a plethora of other ways if you need!).

    2. You also need to add a url endpoint in your urls.py for authentication:

      from my_project/my_app import MyTokenView
      
      urlpatterns = [
          ...
          url(
              r'^my_api/authenticate/$', 
              MyTokenView.as_view(), 
              name='authenticate'),
          ...
      ]
      

    Keep in mind: Since you are extending the TokenView class you should handle the Failure responses as well.