我在各处搜索,这是我找到的。我将尝试从设置cookie到检索cookie的整个过程进行解释。我知道我来晚了,但像我一样,肯定还有其他人在寻找答案。如果我做错了什么,请纠正我。
设置cookie
在
django文档的项目配置下,您会发现他们使用
TokenObtainPairView.as_view()
来获取令牌。我们将在单独的视图文件中修改
TokenObtainPairView
,称之为
MyTokenObtainPairView
并导入它。请参见下面的代码。
from django.urls import path
from .views import MyTokenObtainPairView
urlpatterns = [
path("token/", MyTokenObtainPairView.as_view(), name="token_obtain_pair"),
]
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.views import TokenObtainPairView
class MyTokenObtainPairView(TokenObtainPairView):
def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
token = response.data["access"]
response.set_cookie("pick_a_name_you_like_for_the_cookie", token, httponly=True)
return response
你可以在Postman中测试此功能。 假设您是从根目录并使用localhost进行的,端点应该类似于:
http://localhost:8000/token/
。 您应该使用登录凭据(通常是用户名和密码)运行POST请求。 现在,如果您使用postman,您应该会看到一个名为
pick_a_name_you_like_for_the_cookie
的cookie。
-> 阅读更多(堆栈)
-> 阅读更多(文档)-这更多用于自定义令牌声明。
-
获取令牌
默认情况下,simplejwt将在标头中查找访问令牌。因此,您将无法使用user = request.user
来检索用户,也无法添加权限,例如permission_classes = [IsAuthenticated]
或@permission_classes([IsAuthenticated])
。请参阅文档。
这是因为默认的身份验证类设置为:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
)
}
我们需要复制并修改JWTAuthentication类。在根目录中创建一个名为任何你想要的的文件。在这种情况下,我们创建了
custom_auth.py
。从
rest_framework_simplejwt/authentication.py
复制所有内容。您可以通过进入虚拟环境或直接前往pip安装rest_framework_simplejwt的位置找到此文件。
现在,假设您已经复制了所有内容,请更改
custom_auth.py
中以下代码:
from .exceptions import AuthenticationFailed, InvalidToken, TokenError
from .settings import api_settings
到
from rest_framework_simplejwt.exceptions import AuthenticationFailed, InvalidToken, TokenError
from rest_framework_simplejwt.settings import api_settings
现在,在名为JWTAuthentication
的类内部,您需要将认证函数更改为类似以下内容的函数:
class JWTAuthentication(authentication.BaseAuthentication):
"""
An authentication plugin that authenticates requests through a JSON web
token provided in a request header.
"""
www_authenticate_realm = "api"
media_type = "application/json"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.user_model = get_user_model()
def authenticate(self, request):
cookie = request.COOKIES.get("pick_a_name_you_like_for_the_cookie")
raw_token = cookie.encode(HTTP_HEADER_ENCODING)
validated_token = self.get_validated_token(raw_token)
return self.get_user(validated_token), validated_token
...
如果没有cookie等情况,您应该添加一些验证等操作。可能是这样的:
if cookie is None:
return None
您可以根据需要自定义错误处理方式。最后返回至settings.py并替换:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
)
}
使用:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"custom_auth.JWTAuthentication",
)
}
如果我留下了任何漏洞或者有什么不同的做法,请告诉我!:)
RefreshTokenGrant
。rest_framework_simplejwt.tokens
有RefreshToken
,你是指那个吗?还是这是一个自定义方法? - Jalaluser = authenticate(username=username, password=password)
这一行时,我们是在调用序列化器还是在调用我们在CustomAuthentication类中创建的自定义认证方法? - Jalaluser = authenticate(username=username, password=password)
这个authenticate
是来自于from django.contrib.auth import authenticate
,并且在CustomAuthentication
中继承了JWTAuthentication
。它只检查JWT
令牌是否有效。如果该令牌有效,则用户可以执行特定任务。否则会引发身份验证凭据未提供的错误。 - Pradip Kachhadiya