django(rest_框架)中的令牌身份验证不起作用
标题几乎说明了一切。我正在尝试使用令牌进行身份验证。我正在将django数据库中的信息发送到我的颤振应用程序。我已成功地从rest_框架检索到我的令牌,并将其添加到rest请求的头中。我用django打印了这些标题,结果django(rest_框架)中的令牌身份验证不起作用,django,authentication,django-rest-framework,http-token-authentication,Django,Authentication,Django Rest Framework,Http Token Authentication,标题几乎说明了一切。我正在尝试使用令牌进行身份验证。我正在将django数据库中的信息发送到我的颤振应用程序。我已成功地从rest_框架检索到我的令牌,并将其添加到rest请求的头中。我用django打印了这些标题,结果 { 'Content-Length': '0', 'Content-Type': 'text/plain', 'User-Agent': 'Dart/2.5 (dart:io)', 'Accept-Encoding': 'gzip', 'Author
{
'Content-Length': '0',
'Content-Type': 'text/plain',
'User-Agent': 'Dart/2.5 (dart:io)',
'Accept-Encoding': 'gzip',
'Authorization': 'Token 10cf58e1402b8e48c1a455aaff7f7bcf53e24231',
'Host': '192.168.0.110:8000'
}
然而,结果是带有登录表单的网页,而不是我请求的其余数据。我错过了什么
设置.py
...
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
...
views.py
...
@login_required
@csrf_exempt
def ui_list(request):
print(request.headers)
"""
List all code user_informations, or create a new user_information.
"""
if request.method == "GET":
users = UserInformation.objects.all()
serializer = UserInformationSerializer(users, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == "POST":
data = JSONParser().parse(request)
serializer = UserInformationSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
...
您的问题来自于使用decorator@login_required,它应该保护django视图 Django视图和Django_rest_框架不使用相同的身份验证系统,因此需要以不同的方式实现 手动验证 您可以删除@login_required并实现view.py,如下所示:
from rest_framework.authentication import TokenAuthentication
...
@csrf_exempt
def ui_list(request):
print(request.headers)
"""
List all code user_informations, or create a new user_information.
"""
if request.method == "GET":
user_auth_tuple = TokenAuthentication().authenticate(request)
if user_auth_tuple is None:
return HttpResponse(status=401)
else:
(user, token) = user_auth_tuple # here come your user object
users = UserInformation.objects.all()
serializer = UserInformationSerializer(users, many=True)
return JsonResponse(serializer.data, safe=False)
if request.method == "POST":
...
...
但是手工完成这个过程确实很耗时,不应该这样做,因为DRSF提供了很多选项来实现自动化
基于类的视图
实际上应该做的是匹配模型,并使用权限系统生成适当的入口点
REST框架提供了一个APIView类,它是Django视图类的子类
APIView类与常规视图类在以下方面不同:
传递给处理程序方法的请求将是REST框架的请求实例,而不是Django的HttpRequest实例。
处理程序方法可能返回REST框架的响应,而不是Django的HttpResponse。该视图将管理内容协商并在响应上设置正确的呈现器。
任何APIException异常都将被捕获并调解到适当的响应中。
传入请求将经过身份验证,并在将请求分派给处理程序方法之前运行适当的权限和/或限制检查。
您的问题来自于使用decorator@login_required,它应该保护django视图 Django视图和Django_rest_框架不使用相同的身份验证系统,因此需要以不同的方式实现 手动验证 您可以删除@login_required并实现view.py,如下所示:
from rest_framework.authentication import TokenAuthentication
...
@csrf_exempt
def ui_list(request):
print(request.headers)
"""
List all code user_informations, or create a new user_information.
"""
if request.method == "GET":
user_auth_tuple = TokenAuthentication().authenticate(request)
if user_auth_tuple is None:
return HttpResponse(status=401)
else:
(user, token) = user_auth_tuple # here come your user object
users = UserInformation.objects.all()
serializer = UserInformationSerializer(users, many=True)
return JsonResponse(serializer.data, safe=False)
if request.method == "POST":
...
...
但是手工完成这个过程确实很耗时,不应该这样做,因为DRSF提供了很多选项来实现自动化
基于类的视图
实际上应该做的是匹配模型,并使用权限系统生成适当的入口点
REST框架提供了一个APIView类,它是Django视图类的子类
APIView类与常规视图类在以下方面不同:
传递给处理程序方法的请求将是REST框架的请求实例,而不是Django的HttpRequest实例。
处理程序方法可能返回REST框架的响应,而不是Django的HttpResponse。该视图将管理内容协商并在响应上设置正确的呈现器。
任何APIException异常都将被捕获并调解到适当的响应中。
传入请求将经过身份验证,并在将请求分派给处理程序方法之前运行适当的权限和/或限制检查。
此登录不是rest框架身份验证所需的方式。如果您正试图这样做,则需要使用权限类通过api进行身份验证。
如何实现它,我创建了一个登录视图
class LoginView(APIView):
"""Class based view loggin in user and returning Auth Token."""
authentication_classes = [TokenAuthentication]
permission_classes = [AllowAny]
def post(self, request):
"""Check if user exists, return token if it does."""
data = JSONParser().parse(request)
serializer_obj = LoginObjectSerializer(data=data)
if serializer_obj.is_valid():
user = authenticate(username=serializer_obj.data['username'], password=serializer_obj.data['password'])
if not user:
return Response({'error': 'Invalid Credentials'}, status=404)
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key}, status=200)
return JsonResponse(serializer_obj.errors, status=400)
我是如何通过使用rest框架提供的权限类而不是@login\u required来验证我的API的。
My settings.py具有
我用来保护我的视图的权限类是这样的
from rest_framework.permissions import AllowAny, IsAuthenticated
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
但我在基于类的视图中使用了这种方式。对于基于方法的,您可以按照前面提到的那样执行此操作
问题的关键是,您试图使用基于令牌的身份验证,但实际上并没有使用它。创建您自己的登录api,并像本答案或@sebastienbarbier的答案中提到的那样使用它。需要此登录不是rest框架的身份验证方式。如果您正试图这样做,则需要使用权限类通过api进行身份验证。
如何实现它,我创建了一个登录视图
class LoginView(APIView):
"""Class based view loggin in user and returning Auth Token."""
authentication_classes = [TokenAuthentication]
permission_classes = [AllowAny]
def post(self, request):
"""Check if user exists, return token if it does."""
data = JSONParser().parse(request)
serializer_obj = LoginObjectSerializer(data=data)
if serializer_obj.is_valid():
user = authenticate(username=serializer_obj.data['username'], password=serializer_obj.data['password'])
if not user:
return Response({'error': 'Invalid Credentials'}, status=404)
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key}, status=200)
return JsonResponse(serializer_obj.errors, status=400)
我是如何通过使用rest框架提供的权限类而不是@login\u required来验证我的API的。
My settings.py具有
我用来保护我的视图的权限类是这样的
from rest_framework.permissions import AllowAny, IsAuthenticated
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
但我在基于类的视图中使用了这种方式。对于基于方法的,您可以按照前面提到的那样执行此操作
问题的关键是,您试图使用基于令牌的身份验证,但实际上并没有使用它。创建您自己的登录api,并像本答案或@sebastienbarbier的答案中提到的那样使用它。您应该会收到401次未经授权的访问,因此问题可能在于url或视图,您可以显示更多代码吗?netry point与REST客户端或文档一起工作吗?@sebastienbarbier我已经添加了相关的视图代码
m基于类的视图除外您应该收到401次未经授权的访问,因此问题可能是url或视图,您可以显示更多代码吗?netry point与REST客户端或文档一起工作吗?@sebastienbarbier我已经添加了相关的视图代码。pyI遵循了中的教程,但基于类的视图除外。根据REST_框架文档,如果在http请求中设置了身份验证头,request.user应该包含相关的用户。这将使事情变得更容易。@需要登录时,您不知道DRF http请求,因此认为您的请求未经验证。rest_框架可能引用APIView类提供的自己的请求实例;根据rest_框架文档,如果在http请求中设置了身份验证头,则request.user应该包含相关的用户。这将使事情变得更容易。@需要登录时,您不知道DRF http请求,因此认为您的请求未经验证。rest_框架可能引用APIView类提供的自己的请求实例;