Python Django Rest框架-使用会话和令牌身份验证
我正试图让这项工作,但不知道这是否是可能的。它应该这样做 我使用Python Django Rest框架-使用会话和令牌身份验证,python,django,django-rest-framework,django-rest-framework-simplejwt,Python,Django,Django Rest Framework,Django Rest Framework Simplejwt,我正试图让这项工作,但不知道这是否是可能的。它应该这样做 我使用Django+Rest框架+jQuery开发了一个web应用程序,我希望有一个外部应用程序使用相同的RestAPI,使用JWT令牌进行身份验证 我当前的配置是这样的 设置.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication',
Django
+Rest框架
+jQuery
开发了一个web应用程序,我希望有一个外部应用程序使用相同的Rest
API,使用JWT令牌
进行身份验证
我当前的配置是这样的
设置.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',),
}
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)
视图.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',),
}
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\u classes
而不是permission\u 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
在同一类
视图中一起工作,或者我应该分成两个端点
编辑
使用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>
我无法确定您的案例中到底发生了什么,因为您共享的3个案例中的行为似乎不一致,但简单地解释一下如何在DRF中确定身份验证和授权,这可能会帮助您解决问题 您应该能够毫无问题地使用两个身份验证类。使用DRF,身份验证的工作方式如下:
class ListFileView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, *args, **kwargs):
...
在每个请求中,DRF按照定义的顺序检查提供的身份验证类。对于每个类别,有3种情况:
request.user
。从这一点开始,这个请求就被验证了授权
头中的JWT令牌无效,DRF将引发异常并返回403响应DEFAULT\u AUTHENTICATION\u CLASSES
变量,但如果在视图中提供这些变量,则会覆盖设置
将权限\u类添加到视图中时,授权开始发挥作用permission\u classes
控制对视图的访问,因此当您将IsAuthenticated
添加到视图的权限类中时,如果您试图在没有经过身份验证的用户的情况下访问该视图,DRF将以403响应拒绝该请求
因此,在最初的情况下,您的内部AJAX请求在本例中失败表明您的请求会话中没有经过身份验证的用户数据。我不知道这是什么原因造成的。也许您没有在登录视图中更新请求会话(Django的登录方法应该自动完成这项工作)
在第二种情况下,从视图中删除权限类
,因此无论请求中是否有经过身份验证的用户,视图都将为请求提供服务。因此,我们期望您的内部AJAX请求在这里成功,但我不知道为什么您的外部请求在这种情况下失败
在第三种情况下,从内部AJAX请求的角度来看,场景似乎与第一种情况相同,因此我不知道为什么内部AJAX请求在这种情况下成功,但在第一种情况下没有成功。预期外部请求在此失败,因为您将IsAuthenticated
权限类添加到视图中,但未将JWTAuthentication
包含在身份验证类中,因此,您的请求无法在此处使用JWT令牌进行身份验证。您可以显示如何调用API吗?@JPG使用jQuery
或外部调用?@JPG添加了jQuery
和VBA
示例调用。您也可以发布登录视图吗?您是否使用Django的登录方法?是的,我使用的是标准Django登录您是对的,谢谢您的详细解释。事实证明,我实际上在生产中使用了一个错误的settings.py
文件,该文件缺少DRFDEFAULT\u authentication\u CLASSES
中的这一行rest\u framework.authentication.SessionAuthentication
,现在工作正常。