Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django(rest_框架)中的令牌身份验证不起作用_Django_Authentication_Django Rest Framework_Http Token Authentication - Fatal编程技术网

django(rest_框架)中的令牌身份验证不起作用

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

标题几乎说明了一切。我正在尝试使用令牌进行身份验证。我正在将django数据库中的信息发送到我的颤振应用程序。我已成功地从rest_框架检索到我的令牌,并将其添加到rest请求的头中。我用django打印了这些标题,结果

{
  '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类提供的自己的请求实例;