Django:将数据添加到 JWT 负载

Django: Add data to JWT payload

我想将数据(例如令牌到期日期或用户信息)添加到 this library 生成的 JWT 的负载中。

此库生成的 JWT 的当前解码负载如下:

{
  "token": "sXF6EE6jlZRmKhx1mgodOCdUMuSE1I"
}

我想要这样的东西

{
  "expiration_date": 1588329561
}

我没有实现任何序列化程序或视图,因为库管理序列化程序和视图。

我只需要在 urls.py 文件中声明以下 URL:

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

然后我可以发出 POST 请求来生成或刷新 JWT 到 auth/token/

我见过(使用其他库的人的)尝试修改库的解决方案,以及其他实现序列化程序和视图的解决方案,但由于我使用的库负责此任务,我不知道如何解决这个问题。

注:

drf-social-oauth2 不提供轻松覆盖此设置的机制,它使用 generate_token 方法 (https://github.com/wagnerdelima/drf-social-oauth2/blob/master/drf_social_oauth2/settings.py#L11-L14) 覆盖 oauth2_provider.settings.ACCESS_TOKEN_GENERATOR,此方法不包括额外的值,只有令牌。

您可以在自己这边做同样的事情,使用添加所需键的自定义方法覆盖该值。

我按照@omab 的建议做了以下操作:

步骤 1)

在您的应用程序中创建一个文件(例如 app/token_generator.py)并粘贴 following function inside.

步骤 2)

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'
}

示例(我的情况):

我想将到期日期添加到令牌负载中,所以我执行了以下操作:

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