使用 django rest framework jwt 向 JWT 令牌主体添加信息
Adding information to JWT token body using django rest framework jwt
我正在使用 django rest 框架和 djangorestframework-jwt 包来创建 JWT 令牌以进行授权。
在前端,我可以解码令牌并获取用户名、电子邮件和 user_id。但是我想检索一些额外的信息。例如,如果我能得到 kind
这是我们授权模型(用户模型)上的一个字段,那将非常方便。
我当然可以单独请求通过常规 APIView 获取用户信息。但我想知道是否可以在 JWT 主体中添加一些额外的参数?
如本 github issue 中所详述,我是通过从 DRF-JWT:
中插入 ObtainJSONWebToken
class 来完成此操作的
from rest_framework_jwt import views as jwt_views
from .serializers import UserSerializer
class UserLoginViewJWT(jwt_views.ObtainJSONWebToken):
user_serializer_class = UserSerializer
def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
if response.status_code == status.HTTP_200_OK:
user = get_user_model().objects.get(email=request.data[get_user_model().USERNAME_FIELD])
serialized_user = self.user_serializer_class(user)
response.data.update(serialized_user.data)
return response
注意: 上面的代码可能缺少一些导入
@jpadilla 的回复还指出
You can also do this with the JWT_RESPONSE_PAYLOAD_HANDLER setting.
http://getblimp.github.io/django-rest-framework-jwt/#jwt_response_payload_handler
使用 djangorestframework_simplejwt 库
在settings.py中指定USER_ID_FIELD和算法
SIMPLE_JWT = {
'USER_ID_FIELD': 'user_id',
'ALGORITHM': 'HS512',
}
假设您要将字段添加到具有以下主体的 TokenObtainPairView 主体
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU5MDk5ODAwMSwianRpIjoiMjZhZThhYTU4YTJiNDU3M2JlMDgxNTMzMzU1ODg4ZmUiLCJ1c2VyX2lkIjoxMX0.-jUCnfpTF-RsqHnuoEgctPpHf1SfYNcYaPs8oo01RvrQBMcyhms5PfWipfYkaR0FlPHSTKncNeMxomwd4k7nyg",
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTExOTAxLCJqdGkiOiI5NjZkOTFhNzEzNjg0NjMyOGUzYWU3NThiNzNiZmYxMyIsInVzZXJfaWQiOjExfQ.LiHrekmlHrM7_5187ghpIaA6mKcPCjDz4MDKPXHc4QAKVGvcJCJpCjrODCB4-pZn4Kuai5ht3YjWwYSirxpsXw"
}
加入你的urls.py
path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain'),
创建 MyTokenObtainPairView
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer`
创建 MyTokenObtainPairSerializer
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data.pop('refresh', None) # remove refresh from the payload
data['access'] = str(refresh.access_token)
# Add extra responses here
data['user'] = self.user.username
data['kind'] = self.user.kind
data['date'] = datetime.date.today()
return data
这样当你 post 到 /api/token/ 你会得到像这样的东西
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTEwNTc0LCJqdGkiOiIwM2Q5MzA1NTZmNzk0NmFjODU1MzJlNTYzNjUwZDY0MCIsInVzZXJfaWQiOjExfQ.H0huO84qtzdbo4OkKhsW_vtNTGwInG67gum6f138h1y66EiyZ1BvxaxbfEE2oPG4pB0XjiWQrXc5PlR9C6UvfQ",
"user": "tiago",
"kind": "whatever_this_has"
"date": "2020-05-31"
}
我正在使用 django rest 框架和 djangorestframework-jwt 包来创建 JWT 令牌以进行授权。
在前端,我可以解码令牌并获取用户名、电子邮件和 user_id。但是我想检索一些额外的信息。例如,如果我能得到 kind
这是我们授权模型(用户模型)上的一个字段,那将非常方便。
我当然可以单独请求通过常规 APIView 获取用户信息。但我想知道是否可以在 JWT 主体中添加一些额外的参数?
如本 github issue 中所详述,我是通过从 DRF-JWT:
中插入ObtainJSONWebToken
class 来完成此操作的
from rest_framework_jwt import views as jwt_views
from .serializers import UserSerializer
class UserLoginViewJWT(jwt_views.ObtainJSONWebToken):
user_serializer_class = UserSerializer
def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
if response.status_code == status.HTTP_200_OK:
user = get_user_model().objects.get(email=request.data[get_user_model().USERNAME_FIELD])
serialized_user = self.user_serializer_class(user)
response.data.update(serialized_user.data)
return response
注意: 上面的代码可能缺少一些导入
@jpadilla 的回复还指出
You can also do this with the JWT_RESPONSE_PAYLOAD_HANDLER setting. http://getblimp.github.io/django-rest-framework-jwt/#jwt_response_payload_handler
使用 djangorestframework_simplejwt 库
在settings.py中指定USER_ID_FIELD和算法
SIMPLE_JWT = { 'USER_ID_FIELD': 'user_id', 'ALGORITHM': 'HS512', }
假设您要将字段添加到具有以下主体的 TokenObtainPairView 主体
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTU5MDk5ODAwMSwianRpIjoiMjZhZThhYTU4YTJiNDU3M2JlMDgxNTMzMzU1ODg4ZmUiLCJ1c2VyX2lkIjoxMX0.-jUCnfpTF-RsqHnuoEgctPpHf1SfYNcYaPs8oo01RvrQBMcyhms5PfWipfYkaR0FlPHSTKncNeMxomwd4k7nyg",
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTExOTAxLCJqdGkiOiI5NjZkOTFhNzEzNjg0NjMyOGUzYWU3NThiNzNiZmYxMyIsInVzZXJfaWQiOjExfQ.LiHrekmlHrM7_5187ghpIaA6mKcPCjDz4MDKPXHc4QAKVGvcJCJpCjrODCB4-pZn4Kuai5ht3YjWwYSirxpsXw"
}
加入你的urls.py
path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain'),
创建 MyTokenObtainPairView
class MyTokenObtainPairView(TokenObtainPairView): serializer_class = MyTokenObtainPairSerializer`
创建 MyTokenObtainPairSerializer
class MyTokenObtainPairSerializer(TokenObtainPairSerializer): def validate(self, attrs): data = super().validate(attrs) refresh = self.get_token(self.user) data['refresh'] = str(refresh) data.pop('refresh', None) # remove refresh from the payload data['access'] = str(refresh.access_token) # Add extra responses here data['user'] = self.user.username data['kind'] = self.user.kind data['date'] = datetime.date.today() return data
这样当你 post 到 /api/token/ 你会得到像这样的东西
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTEwNTc0LCJqdGkiOiIwM2Q5MzA1NTZmNzk0NmFjODU1MzJlNTYzNjUwZDY0MCIsInVzZXJfaWQiOjExfQ.H0huO84qtzdbo4OkKhsW_vtNTGwInG67gum6f138h1y66EiyZ1BvxaxbfEE2oPG4pB0XjiWQrXc5PlR9C6UvfQ",
"user": "tiago",
"kind": "whatever_this_has"
"date": "2020-05-31"
}