'django-oauth-toolkit : Customize authenticate response

I am new to Django OAuth Toolkit. I want to customize the authenticate response.

My authenticate url configuration on django application is :

url('authenticate/',
    include('oauth2_provider.urls', namespace='oauth2_provider'))

https://django-oauth-toolkit.readthedocs.io/en/latest/install.html

Now, when i launch this command :

curl -X POST -d 'grant_type=password&username=$username&password=$password'
 -u "$client_id:$client_secret" http://127.0.0.1:8000/authenticate/token/

I get this response :

{
   "access_token": "ATiM10L0LNaldJPk12drXCjbhoeDR8",
   "expires_in": 36000,
   "refresh_token": "II4UBhXhpVDEKWmsUQxDzkj3OMjW1p",
   "scope": "read groups write",
   "token_type": "Bearer"
}

And would like this response :

{
   "access_token": "ATiM10L0LNaldJPk12drXCjbhoeDR8",
   "expires_in": 36000,
   "refresh_token": "II4UBhXhpVDEKWmsUQxDzkj3OMjW1p",
   "scope": "read groups write",
   "token_type": "Bearer",
   "member": {
      "id": 1,
      "username": "username",
      "email": "[email protected]",
      ....
   }
}

I just want to override this response for add information of authenticated user. I have read the documentation of django-oauth-toolkit. And i didn't find a solution to my problem...



Solution 1:[1]

Not sure how many people use drf_social_oauth2 but you can also do the same with that. Here is my solution overwriting the drf-social-oauth2 Token View

url(r"authenticate/token/$", CustomTokenView.as_view(), name="token"),

views.py

import json
from rest_framework.response import Response
from drf_social_oauth2.views import TokenView
from oauth2_provider.models import get_access_token_model, get_application_model
from oauth2_provider.signals import app_authorized


class CustomTokenView(TokenView):
    def post(self, request, *args, **kwargs):
         mutable_data = request.data.copy()
          request._request.POST = request._request.POST.copy()
           for key, value in mutable_data.items():
                request._request.POST[key] = value
            url, headers, body, status = self.create_token_response(
                request._request)
            if status == 200:
                body = json.loads(body)
                access_token = body.get("access_token")
                if access_token is not None:
                    token = get_access_token_model().objects.get(
                        token=access_token)
                    app_authorized.send(
                        sender=self, request=request,
                        token=token)
                    body['member'] = {
                        'id': token.user.id,
                        'username': token.user.username,
                        'email': token.user.email
                    }
                    body = json.dumps(body)
            response = Response(data=json.loads(body), status=status)

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

     

Solution 2:[2]

This too can work

import json

from oauth2_provider.models import get_access_token_model
from oauth2_provider.views import TokenView as OAuth2TokenView


class TokenView(OAuth2TokenView):
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        body = json.loads(response.content)
        access_token = body.get("access_token")
        token = get_access_token_model().objects.get(token=access_token)
        body["member"] = {
            "id": token.user.id,
            "email": token.user.email,
            "username": token.user.username,
        }
        response.content = json.dumps(body)
        return response

and in urls.py add

    path("o/token/", TokenView.as_view(), name="token"),
    path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")),

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 digitaluniverse
Solution 2 Esir Kings