Django:将数据添加到 JWT 负载

问题描述

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

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

{
  "token": "sXF6EE6jlZRmKhx1mgodoCdUMuSE1I"
}

我想要这样的东西

{
  "expiration_date": 1588329561
}

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

我只需在 urls.py 文件中声明以下网址:

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

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

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

注意:

  • drf-social-auth2 的维护者表示它依赖于 python-social-authdjango-oauth-toolkit

解决方法

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

您可以使用添加所需键的自定义方法覆盖该值。

,

我按照@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