Django REST:如何将SimpleJWT访问和刷新令牌作为具有自定义声明的HttpOnly cookie返回?

Django REST:如何将SimpleJWT访问和刷新令牌作为具有自定义声明的HttpOnly cookie返回?,django,cookies,django-rest-framework,django-rest-framework-simplejwt,cookie-httponly,Django,Cookies,Django Rest Framework,Django Rest Framework Simplejwt,Cookie Httponly,我想通过HttpOnlycookie发送SimpleJWTaccess和refresh令牌。我已经定制了索赔。我在设置cookie的MyObtainTokenPairView(tokenacceptainpairview)中定义了一个post()方法。这是我的代码: from .models import CustomUser class MyObtainTokenPairView(TokenObtainPairView): permission_classes = (permissi

我想通过
HttpOnly
cookie发送
SimpleJWT
access和
refresh
令牌。我已经定制了索赔。我在设置cookie的
MyObtainTokenPairView(tokenacceptainpairview)
中定义了一个
post()
方法。这是我的代码:

from .models import CustomUser

class MyObtainTokenPairView(TokenObtainPairView):
    permission_classes = (permissions.AllowAny,)
    serializer_class = MyTokenObtainPairSerializer
    
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class()
        response = Response()
        tokens = serializer.get_token(CustomUser)
        access = tokens.access
        response.set_cookie('token', access, httponly=True)
        return response   
它将返回以下错误:

AttributeError: 'RefreshToken' object has no attribute 'access'
序列化程序:

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    
    @classmethod
    def get_token(cls, user):
        print(type(user))
        token = super().get_token(user)
        token['email'] = user.email
        return token
但它就是不起作用。我想我不应该在这里像这样定义
post()
方法。我认为如果我只能返回序列化程序中
get_token()
函数的值,我可以将其设置为
HttpOnly
cookie。但是,我不知道怎么做

如何在
HttpOnly
cookie中设置
access
refresh
令牌

编辑: 我根据anowlinorbit的回答做了以下更改:

我将序列化程序更改为:

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    
    def validate(self, attrs):
        attrs = super().validate(attrs)
        token = self.get_token(self.user)
        token["email"] = self.user.email
        return token
由于此令牌默认包含刷新令牌,因此我决定仅返回此
令牌
将提供
访问
刷新
令牌。 如果我添加类似于
token[“access”]=str(token.access\u token)
的内容,它只会将访问令牌字符串添加到刷新令牌字符串中,刷新令牌字符串已经包含了

但是在视图中,我仍然找不到如何获取刷新令牌。我无法使用
serializer.validated\u data.get('refresh',None)
获取它,因为现在我正在从包含所有内容的序列化程序返回
标记

我改变了我的观点:

class MyObtainTokenPairView(TokenObtainPairView):
    permission_classes = (permissions.AllowAny,)
    serializer_class = MyTokenObtainPairSerializer
    
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        response.set_cookie('token', token, httponly=True)
        return response
现在它说:

NameError: name 'token' is not defined

这里怎么了?在视图中,我希望获取从序列化程序返回的
令牌
,然后使用
令牌获取acces令牌。访问\u令牌
,并将
刷新
访问
都设置为cookie。

我将不使用
.get\u令牌()
而只关注
.validate()
。在您的
MyTokenActainPairSerializer
中,我将删除您对
的更改。获取\u token()
并添加以下内容

def验证(自身、属性):
data=super().validate(attrs)
刷新=self.get_令牌(self.user)
data[“refresh”]=str(refresh)#如果您不想这样做,请将其注释掉
数据[“访问”]=str(刷新.访问\u令牌)
数据[“电子邮件”]=self.user.email
“”“如果您愿意,请在此处添加额外的响应。”
数据[“userid”]=self.user.id
数据[“我最喜欢的鸟”]=“杰克鹬”
"""
返回数据
通过使用
.validate()
方法,您可以选择希望从序列化程序对象的
validated\u data
属性返回哪些数据N.B.我还将刷新令牌包含在序列化程序返回的数据中。同时拥有刷新和访问令牌非常重要。如果用户没有刷新令牌,那么当访问令牌过期时,他们必须再次登录。刷新令牌允许他们获得新的访问令牌,而无需再次登录

如果出于任何原因不需要刷新令牌,请将其从
validate()
serializer方法中删除,并相应地调整视图

在这个post方法中,我们验证序列化程序并访问其验证的数据

def post(self、request、*args、**kwargs):
#您需要用请求数据实例化序列化程序
serializer=self.serializer(data=request.data)
#在访问已验证的\u数据之前,必须调用.is\u valid()
serializer.is\u有效(raise\u exception=True)
#获取访问权并刷新令牌,以执行您喜欢的操作
access=serializer.validated\u data.get(“access”,无)
刷新=序列化程序。已验证的\u数据。获取(“刷新”,无)
email=serializer.validated\u data.get(“email”,无)
#构建您的响应并设置cookie
如果访问权限不是“无”:
响应=响应({“访问”:访问,“刷新”:刷新,“电子邮件”:电子邮件},状态=200)
response.set_cookie('token',access,httponly=True)
response.set_cookie('refresh',refresh,httponly=True)
response.set_cookie('email',email,httponly=True)
返回响应
返回响应({“Error”:“出错”,状态=400)

如果您不想要刷新令牌,您可以删除以
refresh=
开头的行,并删除添加
refresh
cookie的行。

请查看我的编辑,我被困在
视图中。
。更新了答案。谢谢!您保存了我的背部,使其正常工作。但是令牌clai中遗漏了
电子邮件
m、 我用电子邮件更新了代码。您将看到一种模式:首先,在序列化程序中定义数据,使用serializer.validated_data.get()获取数据,然后根据需要使用此获取的数据。