当前位置:   article > 正文

python测试开发django-rest-framework-61.权限认证(permission)

rest_framework.permissions.allowany

前言

用户登录后,才有操作当前用户的权限,不能操作其它人的用户,这就是需要用到权限认证,要不然你登录自己的用户,去操作别人用户的相关数据,就很危险了。

  • authentication是身份认证,判断当前用户的登录方式是哪种认证方式
  • permissions 是权限认证,判断哪些用户有操作权限

authentication身份认证

身份验证是将收到的请求和一组标识证书(如用户名密码、令牌)进行关联的一种机制,以便权限和策略可以根据这个标识证书来决定是否允许该请求。因此,身份验证发生在验证权限和限制检查之前。

当收到的请求通过身份验证时:

  • request.user属性会设置为django.contrib.auth.User对象,即我们登录的对象(我们定义用户继承于User)。
  • request.auth会设置为对应的Token(如果带有Token)或者None(如果不带有Token)。
    当收到请求身份验证失败时:

  • request.user属性会设置为django.contrib.auth.models.AnonymousUser对象。
  • request.auth会设置为None。

django rest framework权限和认证有四种方式:

  • BasicAuthentication 此身份验证方案使用HTTP基本身份验证,根据用户的用户名和密码进行签名。基本身份验证通常仅适用于测试
  • TokenAuthentication 此身份验证方案使用基于令牌的简单HTTP身份验证方案。令牌认证适用于客户端 - 服务器设置,例如本机桌面和移动客户端。
  • SessionAuthentication 此身份验证方案使用Django的默认会话后端进行身份验证。会话身份验证适用于与您的网站在同一会话上下文中运行的AJAX客户端。
  • RemoteUserAuthentication 此身份验证方案允许您将身份验证委派给Web服务器,该服务器设置REMOTE_USER 环境变量。

permission权限认证

权限检查通常使用request.user和request.auth属性中的身份验证信息来确定是否应允许传入请求。

当权限检查失败时,将根据以下规则返回HTTP 403 Forbidden或HTTP 401 Unauthorized:

  • 如果收到的请求身份验证通过,但是权限验证失败,则返回HTTP 403 Forbidden;
  • 如果收到的请求身份验证失败,且最高优先级验证类不能使用WWW-Authenticate请求头,则返回HTTP 403 Forbidden;
  • 如果收到的请求身份验证失败,且最高优先级验证类可以使用WWW-Authenticate请求头,则返回HTTP 401 Unauthorized

权限级别也有四种

  • AllowAny 允许所有用户
  • IsAuthenticated 表示仅仅允许身份验证通过的用户访问,其他用户无法访问。
  • IsAdminUser 表示仅仅允许管理员用户访问,普通用户无法访问。
  • IsAuthenticatedOrReadOnly 表示仅仅允许身份验证通过的用户访问,或者只允许只读请求(GET请求)访问。

相关配置

在settings.py中,INSTALLED_APPS添加rest_framework和rest_framework.authtoken

  1. INSTALLED_APPS = [
  2. 'apiapp',
  3. 'rest_framework.authtoken',
  4. 'rest_framework',
  5. ]

REST_FRAMEWORK添加权限认证方式和身份认证方式

  1. REST_FRAMEWORK = {
  2. # 权限认证
  3. 'DEFAULT_PERMISSION_CLASSES': (
  4. 'rest_framework.permissions.IsAuthenticated', # IsAuthenticated 仅通过认证的用户
  5. 'rest_framework.permissions.AllowAny', # AllowAny 允许所有用户
  6. 'rest_framework.permissions.IsAdminUser', # IsAdminUser 仅管理员用户
  7. 'rest_framework.permissions.IsAuthenticatedOrReadOnly', # IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取
  8. ),
  9. # 身份认证
  10. 'DEFAULT_AUTHENTICATION_CLASSES': (
  11. 'rest_framework.authentication.BasicAuthentication',
  12. 'rest_framework.authentication.SessionAuthentication',
  13. 'rest_framework.authentication.TokenAuthentication', # token认证
  14. )
  15. }

登录生成token

登录的时候,不需要身份认证,permission_classes设置成AllowAny,允许所有的用户

permission_classes = (AllowAny,) # AllowAny 允许所有用户

  1. from django.http import JsonResponse
  2. from django.shortcuts import HttpResponse
  3. from rest_framework.authtoken.models import Token
  4. from django.contrib import auth
  5. from rest_framework.views import APIView
  6. from rest_framework import viewsets
  7. from rest_framework import serializers
  8. from .models import *
  9. from django.http import QueryDict
  10. from rest_framework.request import Request
  11. from rest_framework.permissions import IsAuthenticated,AllowAny
  12. from rest_framework.authentication import TokenAuthentication
  13. '''作者:上海悠悠,QQ交流群:750815713'''
  14. class LoginViewSet(APIView):
  15. '''登录获取token方法'''
  16. permission_classes = (AllowAny,) # AllowAny 允许所有用户
  17. def post(self, request, *args, **kwargs):
  18. username = request.data.get('username')
  19. # print(username)
  20. password = request.data.get('password')
  21. user = auth.authenticate(username=username, password=password)
  22. if not user:
  23. return HttpResponse({"code": 0,
  24. "msg": "用户名或密码不对!"})
  25. # 删除原有的Token
  26. old_token = Token.objects.filter(user=user)
  27. old_token.delete()
  28. # 创建新的Token
  29. token = Token.objects.create(user=user)
  30. return JsonResponse({"code": 0,
  31. "msg": "login success!",
  32. "username": user.username,
  33. "token": token.key})

添加card相关信息,接着前面一篇讲的,添加authentication_classes和permission_classes

authentication_classes = (TokenAuthentication,) # token认证
permission_classes = (IsAuthenticated,) # # IsAuthenticated 仅通过认证的用户

  1. def get_parameter_dic(request, *args, **kwargs):
  2. # 作者:上海悠悠,QQ交流群:750815713
  3. if isinstance(request, Request) == False:
  4. return {}
  5. query_params = request.query_params
  6. if isinstance(query_params, QueryDict):
  7. query_params = query_params.dict()
  8. result_data = request.data
  9. if isinstance(result_data, QueryDict):
  10. result_data = result_data.dict()
  11. if query_params != {}:
  12. return query_params
  13. else:
  14. return result_data
  15. class CardSerializer(serializers.HyperlinkedModelSerializer):
  16. class Meta:
  17. model = Card
  18. fields = "__all__"
  19. class CardViewSet(viewsets.ModelViewSet):
  20. '''# 作者:上海悠悠,QQ交流群:750815713'''
  21. authentication_classes = (TokenAuthentication,) # token认证
  22. permission_classes = (IsAuthenticated,) # # IsAuthenticated 仅通过认证的用户
  23. queryset = Card.objects.all()
  24. serializer_class = CardSerializer
  25. def get(self, request, *args, **kwargs):
  26. params=get_parameter_dic(request)
  27. return JsonResponse(data=params)
  28. def post(self, request, *args, **kwargs):
  29. params=get_parameter_dic(request)
  30. return JsonResponse(data=params)
  31. def put(self, request, *args, **kwargs):
  32. params=get_parameter_dic(request)
  33. return JsonResponse(data=params)

models.py设计card表

  1. class Card(models.Model):
  2. '''银行卡 基本信息 # 作者:上海悠悠,QQ交流群:750815713'''
  3. card_id = models.CharField(max_length=30, verbose_name="卡号", default="")
  4. card_user = models.CharField(max_length=10, verbose_name="姓名", default="")
  5. add_time = models.DateField(auto_now=True, verbose_name="添加时间")
  6. class Meta:
  7. verbose_name_plural = '银行卡账户'
  8. verbose_name = "银行卡账户_基本信息"
  9. def __str__(self):
  10. return self.card_id

urls.py添加方法地址

  1. from apiapp import views
  2. from django.conf.urls import url
  3. from rest_framework import routers
  4. from django.conf.urls import include
  5. # 作者:上海悠悠,QQ交流群:750815713
  6. router = routers.DefaultRouter()
  7. router.register(r'cards', views.CardViewSet)
  8. urlpatterns = [
  9. url(r'^api/v1/login/$', views.LoginViewSet.as_view()),
  10. url(r'^', include(router.urls)),
  11. ]

测试接口

先获取登录token,把token值复制出来:1c0debb44fa0054d312616e7000ae78ce396df8e

  1. {
  2. "code": 0,
  3. "msg": "login success!",
  4. "username": "test",
  5. "token": "1c0debb44fa0054d312616e7000ae78ce396df8e"
  6. }

1070438-20190914102434288-1514522866.png

访问添加银行卡账号的接口时,需在头部带上token,格式为

Authorization: Token 1c0debb44fa0054d312616e7000ae78ce396df8e

带上token去请求的时候,就可以正常的添加成功

1070438-20190914102835708-213576962.png

查看数据库card表会有数据新增成功

1070438-20190914103112043-1029836001.png

如果token错误,或者没有token就会出现401 Unauthorized

1070438-20190914103018896-2037852884.png

转载于:https://www.cnblogs.com/yoyoketang/p/11518524.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/71639
推荐阅读
相关标签
  

闽ICP备14008679号