首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >django (rest_framework)中的令牌身份验证不工作

django (rest_framework)中的令牌身份验证不工作
EN

Stack Overflow用户
提问于 2019-10-30 10:03:04
回答 2查看 4.5K关注 0票数 1

这个标题说明了一切。我正试图用标记来验证身份。我正在从django数据库获取信息到我的应用程序。我已经成功地从rest_framework中检索了我的令牌,并将它添加到rest请求的头中。我在django中打印了这些标题,结果是

代码语言:javascript
复制
{
  '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'
}

但是,结果是带有登录表单的网页,而不是我请求的rest数据。我遗漏了什么?

settings.py

代码语言:javascript
复制
...
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

代码语言:javascript
复制
...
@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)
...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-30 10:58:07

login_required不是rest_framework的身份验证方式。如果您试图通过api进行身份验证,则需要使用权限类进行身份验证。

我如何实现它,我创建了一个登录视图。

代码语言:javascript
复制
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-framework提供的权限类而不是@login_required来验证API的。

代码语言:javascript
复制
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated', )
}

我用来保护我的视图的权限类是这样的

代码语言:javascript
复制
from rest_framework.permissions import AllowAny, IsAuthenticated

authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]

但我在课堂上用过这样的观点。对于基于方法的方法,可以像前面提到的这里那样执行此操作。

代码语言:javascript
复制
@permission_classes([IsAuthenticated])

关键是,您正在尝试使用基于令牌的身份验证,但实际上没有使用它。创建您自己的登录api,并像在这个答案或@sebastienbarbier的回答中那样使用它。

票数 3
EN

Stack Overflow用户

发布于 2019-10-30 10:38:13

您的问题来自于装饰器@login_required的使用,它应该保护一个django视图

Django视图和django_rest_framework 不使用相同的身份验证系统,因此需要以不同的方式实现。

手动认证

您可以删除@login_required并按以下方式实现view.py

代码语言:javascript
复制
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":
         ...
...

但是手动执行这个过程确实是很费时的,不应该这样做,因为提供了很多选项来实现这种自动化。

基于类的视图

实际应该做的是将一个django rest框架APIView类匹配到您的模型,并使用权限系统生成一个适当的入口点。

REST框架提供了一个APIView类,它是Django的视图类的子类。 APIView类是与常规视图类不同的(),其方式如下:

  • 传递给处理程序方法的请求将是REST框架的请求实例,而不是Django的HttpRequest实例。
  • 处理程序方法可能返回REST框架的响应,而不是Django的HttpResponse。视图将管理内容协商和,在响应上设置正确的呈现器。
  • 任何APIException异常都将被捕获并中介到适当的响应中。
  • 传入的请求将经过身份验证,并在将请求发送给处理程序方法之前,将运行适当的权限和/或节流检查。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58622836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档