问题描述
我想向 this library 生成的 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-auth
和django-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