gpt4 book ai didi

python - Django Rest Framework-使用 session 和 token 验证

转载 作者:行者123 更新时间:2023-12-01 11:14:03 26 4
gpt4 key购买 nike

我正在尝试使此工作正常,但不知道是否可行。它应该这样做。

我使用Django + Rest-Framework + jQuery开发了一个Web应用程序,我希望使用REST进行身份验证的外部应用程序使用相同的JWT Tokens API。

我当前的配置是这样的。

settings.py

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_RENDERER_CLASS': [
'rest_framework.renderers.JSONRenderer',
]
}

SIMPLE_JWT = {
'AUTH_HEADER_TYPES': ('Bearer',),
}

views.py
class ListFileView(APIView):
permission_classes = (IsAuthenticated,)

def get(self, request, *args, **kwargs):
user = request.user

if user:

obj = Foo.objects.filter(owner=user)
serializer = FooSerializer(obj, many=True)
data = serializer.data

return Response(data, status=status.HTTP_200_OK)

return Response({'detail': 'You have no access to files.'}, status=status.HTTP_400_BAD_REQUEST)

棘手的部分是当我使用时:
permission_classes = (IsAuthenticated,)

我可以从外部应用程序执行 ajax调用(使用有效的 JWT token ),但是从应用程序内部(经过身份验证的用户)进行的 jQuery调用失败:
{"detail":"Authentication credentials were not provided."}

另一方面,如果我使用 autentication_classes而不是 permission_classes:
authentication_classes = (SessionAuthentication, BasicAuthentication)

我可以使用 jQuery从Web应用程序内执行Ajax调用,但外部调用失败,并出现相同的 403错误。

我试过像这样使用两者:
class ListFileView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)

def get(self, request, *args, **kwargs):
...

但外部调用也被拒绝。

是否可以在同一 Auth View 中将这两种类型的 class一起使用,还是应该分成两个端点?

编辑

在应用程序中使用 jQuery进行的示例调用:
<script type="text/javascript">

function loadTblDocs() {
$("#tbl-docs > tbody").empty();

$.ajaxSetup({
headers: { "X-CSRFToken": '{{csrf_token}}' }
});

$.ajax({
type: 'GET',
contentType: "application/json; charset=utf-8",
url: "/api/list/",
dataType: "json",
success: function (data) {
console.log(data);
}
});
};

</script>

并在外部通过 VBA代码:
Set web = CreateObject("WinHttp.WinHttpRequest.5.1")
web.Open "GET", "/api/list/", False
web.SetRequestHeader "Authorization", "Bearer <JWT_TOKEN_HERE>"
web.Send

最佳答案

我无法弄清楚您的情况到底是怎么回事,因为您共享的3种情况下的行为似乎不一致,但是仅说明一下如何在DRF中确定身份验证和授权,这可能会帮助您确定问题出了。

您应该能够使用两个身份验证类,而不会出现任何问题。使用DRF,身份验证的工作方式如下:

在每个请求中,DRF都会按照定义的顺序遍历所提供的身份验证类。对于每个类(class),有3种情况:

  • 如果DRF可以使用当前类对请求进行身份验证,则设置request.user。从这一点开始,此请求已通过身份验证。
  • 如果不存在身份验证凭据,则DRF会跳过该类
  • 如果存在身份验证凭据但无效,例如Authorization header 中的JWT token 无效,则DRF会引发异常并返回403响应。

  • DRF View 通常使用设置文件中定义的 DEFAULT_AUTHENTICATION_CLASSES变量,但是如果在 View 中提供它们,则设置将被覆盖。

    permission_classes添加到 View 时,授权就起作用了。 permission_classes控制对 View 的访问,因此,当您将 IsAuthenticated添加到 View 的权限类中时,如果您尝试在没有经过身份验证的用户的情况下访问该 View ,则DRF会以403响应拒绝该请求。

    因此,在您的初始情况下,内部AJAX请求在这种情况下失败,这表明您的请求 session 中没有经过身份验证的用户数据。我不知道是什么原因造成的。也许您没有在登录 View 中更新请求 session (Django的登录方法应自动执行此操作)。

    在第二种情况下,您将从 View 中删除 permission_classes,因此无论请求中是否有经过身份验证的用户,该 View 都将为请求提供服务。因此,期望您的内部AJAX请求在此成功,但是我不知道为什么在这种情况下您的外部请求失败。

    在您的第三种情况下,从内部AJAX请求的角度来看,情况似乎与第一种情况相同,因此我不知道为什么您的内部AJAX请求在这种情况下会成功,但在第一种情况下不会成功。外部请求在此处失败的原因是预期的,因为您向 View 添加了 IsAuthenticated许可权类,但未在authentication_classes中包括 JWTAuthentication,因此您的请求无法在此处使用JWT token 进行身份验证。

    关于python - Django Rest Framework-使用 session 和 token 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55550089/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com