1

I want to add data (such as the token expiration date or user info) to the payload of the JWT generated by this library.

The current decoded payload of a JWT generated by this library is the following:

{
  "token": "sXF6EE6jlZRmKhx1mgodOCdUMuSE1I"
}

And I want something like this

{
  "expiration_date": 1588329561
}

I don't have any serializer or view implemented, because the library manages the serializers and the views.

I only have to declare the following URL in the urls.py file:

urlpatterns = [
    ...,
    path('auth/', include('drf_social_oauth2.urls', namespace='drf')),
    ...,
]

and then I can make POST requests to generate or refresh the JWTs to auth/token/.

I've seen solutions (of people that use other libraries) that try to modify the library, and others that implement a serializer and a view, but since the library I'm using is in charge of this task, I don't know how to address this problem.

Note:

  • The maintainers of drf-social-auth2 indicate that it relies on python-social-auth and django-oauth-toolkit.

2 Answers2

2

drf-social-oauth2 doesn't provide a mechanism to easily override this setting, it overrides oauth2_provider.settings.ACCESS_TOKEN_GENERATOR with their generate_token method (https://github.com/wagnerdelima/drf-social-oauth2/blob/master/drf_social_oauth2/settings.py#L11-L14), this method doesn't include extra values, only the token.

You can do the same on your side overriding the value with a custom method that adds the needed keys.

omab
  • 3,471
  • 15
  • 23
1

I did what @omab suggested the following way:

Step 1)

Create a file in your application (e.g. app/token_generator.py) and paste the following function inside.

Step 2)

Add the path to your token generator in settings.py.

OAUTH2_PROVIDER = {
    'ACCESS_TOKEN_EXPIRE_SECONDS': 60 * 5,
    #this is my path, you should add yours
    'ACCESS_TOKEN_GENERATOR': 'user_auth.token_generator.token_generator'
}

Example (my case):

I wanted to add the expiration date to the token payload, so I did the following:

try:
    from secrets import SystemRandom
except ImportError:
    from random import SystemRandom


UNICODE_ASCII_CHARACTER_SET = (
    'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' '0123456789'
)


def token_generator(request, length=30, chars=UNICODE_ASCII_CHARACTER_SET):
    """Generates a non-guessable OAuth Json Web Token
    OAuth (1 and 2) does not specify the format of tokens except that they
    should be strings of random characters. Tokens should not be guessable
    and entropy when generating the random characters is important. Which is
    why SystemRandom is used instead of the default random.choice method.
    """
    from django.conf import settings
    from jose import jwt
    from datetime import datetime, timedelta
    import calendar

    rand = SystemRandom()
    secret = getattr(settings, 'SECRET_KEY')
    token = ''.join(rand.choice(chars) for x in range(length))

    expires_in = getattr(settings, 'OAUTH2_PROVIDER')['ACCESS_TOKEN_EXPIRE_SECONDS']
    exp = calendar.timegm((datetime.utcnow() + timedelta(seconds=expires_in)).utctimetuple())
    
    jwtted_token = jwt.encode({'token': token, 'exp': exp}, secret, algorithm='HS256')
    return jwtted_token