Django 授权请求,即使设置了 permissions.AllowAny
Posted
技术标签:
【中文标题】Django 授权请求,即使设置了 permissions.AllowAny【英文标题】:Django authorizing request even if permissions.AllowAny is set 【发布时间】:2021-08-28 18:38:00 【问题描述】:我正在开发一个 Django REST 框架项目。我正在使用 JWT 身份验证,在我的登录视图中,我已将权限类设置为 AllowAny。 '
@decorators.api_view(["POST"])
@decorators.permission_classes([permissions.AllowAny])
def login(request):
print("REQUEST in login = ", request)
try:
username = request.data['username']
print(username)
user = User.objects.get(username=username)
except Exception as e:
return response.Response('username': "User doesn't exist" , status.HTTP_400_BAD_REQUEST)
try:
password = request.data["password"]
print(password)
except:
return response.Response("password": "Password not valid", status.HTTP_400_BAD_REQUEST)
user = authenticate(username=username, password=password)
if user is not None:
refresh = RefreshToken.for_user(user)
res =
"message": "Logged in successfully",
"refresh": str(refresh),
"access": str(refresh.access_token),
return response.Response(res, status.HTTP_200_OK)
else:
return response.Response("password": "Password not valid", status=status.HTTP_400_BAD_REQUEST)
当我发送正常请求时,一切都按预期工作。
但是当我将 Authorization 标头设置为空字符串时(或 null 两者都有相同的问题)
授权:null 或 ''
Authorization之所以设置为null,是因为React中的axios。它在本地存储中查找访问令牌。如果不存在,则将其设置为 null。
const axiosInstance = axios.create(
baseURL: baseURL,
timeout: 60000,
headers:
Authorization: localStorage.getItem('access_token')
? 'Bearer ' + localStorage.getItem('access_token')
: null,
'Content-Type': 'application/json',
accept: 'application/json',
,
);
我已经在 django 中将默认身份验证设置为 JWT。
REST_FRAMEWORK =
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
我可以考虑在登录时删除 Authorization 标头并设置新的 axiosInstance。但这会使代码不那么清晰。请提出任何解决此问题的方法。
【问题讨论】:
【参考方案1】:您可以提供rest_framework_simplejwt.authentication.JWTAuthentication
的自定义子类,并以您喜欢的方式处理标头的值。
import re
from rest_framework_simplejwt.authentication import JWTAuthentication
class CustomJWTAuthentication(JWTAuthentication):
def get_header(self, request):
header = super().get_header(request)
# value is usually "Bearer <token>"
if header is None:
return header
if not re.match("Bearer \S+", header)
return None
return header
我们这样做是因为JWTAuthentication
只会在JWTAuthentication.get_header()
返回None
时跳过检查,否则它将继续进行。
因此,在 axios 中提供诸如 null
、undefined
或空字符串之类的值将发送它的字符串表示形式(例如,null
将是“null”)并且JWTAuthentication
将按原样处理。
在 django 之外但在 axios 中的另一个解决方案是不通过 tranformRequest
包含它。
const apiAxios = axios.create(
baseURL: baseURL.href,
transformRequest: [
function (data, headers)
const accessToken = window.localStorage.getItem("accessToken")
if (accessToken)
headers['Authorization'] = `Bearer $accessToken`
else
delete headers.Authorization
return JSON.stringify(data)
],
headers: defaultApiHeaders,
);
【讨论】:
以上是关于Django 授权请求,即使设置了 permissions.AllowAny的主要内容,如果未能解决你的问题,请参考以下文章
Facebook 授权 w/permissions 请求产生“页面未找到”
Flutter Permissions 状态 NotAgain 即使在第一次启动时