我正在尝试使其工作,但不知道是否可行。它应该这样做。
我使用Django
+ Rest-Framework
+ jQuery
开发了一个Web应用程序,我希望有一个外部应用程序可以使用{{1 }}进行身份验证。
我当前的配置是这样的。
settings.py
REST
views.py
JWT Tokens
棘手的部分是当我使用时:
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',),
}
我可以从外部应用程序执行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
另一方面,如果我使用jQuery
而不是{"detail":"Authentication credentials were not provided."}
:
autentication_classes
我可以使用permission_classes
从Web应用程序内执行ajax调用,但是外部调用失败,并出现相同的authentication_classes = (SessionAuthentication, BasicAuthentication)
错误。
我尝试过这样使用两者:
jQuery
但是外部呼叫也被拒绝。
是否可以在同一403
视图中同时使用这两种类型的class ListFileView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, *args, **kwargs):
...
,还是应该分成两个端点?
编辑
使用Auth
从应用程序内部进行调用的示例:
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>
答案 0 :(得分:2)
我无法确切了解您的情况,因为您共享的3种情况下的行为似乎不一致,但仅解释一下如何在DRF中确定身份验证和授权,这可能帮助您解决问题。
您应该能够毫无问题地使用两个身份验证类。使用DRF,身份验证的工作方式如下:
在每个请求中,DRF都按照定义的顺序遍历提供的身份验证类。对于每个班级,有3种情况:
DRF视图通常使用设置文件中定义的 authentication_classes ,但是如果在视图中提供它们,则设置将被覆盖。
当您在视图中添加 permission_classes 时,授权就起作用了。 Permission_classes控制对视图的访问,因此,当您在视图的权限类中添加 IsAuthenticated 时,如果您尝试在没有经过身份验证的用户的情况下访问该视图,则DRF会以403响应拒绝请求。
因此,在您的初始情况下,内部ajax请求在这种情况下失败,这表明您的请求会话中没有经过身份验证的用户数据。我不知道是什么原因造成的,也许您未在登录视图中更新请求会话(django的登录方法应自动执行此操作)。
在第二种情况下,您从视图中删除了 permission_classes ,因此无论请求中是否有经过身份验证的用户,视图都将为请求提供服务。因此,可以预期您的内部ajax请求在此成功,但是我不知道为什么在这种情况下您的外部ajax请求失败。
在您的第三种情况下,从内部ajax请求的角度来看,方案似乎与第一种情况相同,因此我不知道为什么您的内部ajax请求在这种情况下会成功,但在第一种情况下不会成功。外部请求在此处失败的原因是,您向视图添加了 IsAuthenticated 权限类,但在authentication_classes中不包含 JWTAuthentication ,因此您的请求无法使用JWT令牌进行身份验证在这里。