认证、权限、频率

1、认证

1.1基本使用

 1# 作用:校验用户是否登录,如果登录了,继续往后走,如果没有登录,直接返回
2
3# 首先得写一个登录功能---》
4
5
6# 认证的使用
7    -第一步:写一个认证类,继承BaseAuthentication,重写authenticate  方法
8    -第二步:在 authenticate 方法中判断用户是否登录(取出用户携带的token,去判断)
9    -第三步:如果认证通过,返回两个值,如果认证不通过抛异常
10        -# 在后续的request对象中,有这两个值,第一个给了request.user,第二个值给了request.auth
11    -第四步:把写的认证类,配置在视图类中(跟请求和响应的配置一样),全局配置
12
13
14
15# 写一个认证类,继承BaseAuthentication
16    -鸭子类型:不显示的继承某个类,只要类中有共同的属性和方法,我们就属于同一类

1.2登录功能

 1# views.py
2
3from rest_framework.viewsets import ViewSet  
4# ViewSet继承了ViewSetMixin类,可以使用自动生成路由,自定义函数需要添加action装饰器
5class Login(ViewSet):
6    authentication_classes = []  # 局部配置认证
7
8    @action(methods=['POST'], detail=False)  # 映射post请求
9    # methods可以写多个请求,detail相当于id值,还可以添加一个name属性,如果写了name属性,那么路径就是前缀加name的value值,没有就默认函数名
10    def login(self, requset):
11        username = requset.data.get('username')
12        password = requset.data.get('password')
13        user = models.UserInfo.objects.filter(username=username, password=password).first()
14        if user:
15            token = uuid.uuid4()
16            models.UserToken.objects.update_or_create(defaults={'token': token}, user=user)
17            # 由于user表与token表是一对一关系,token字段有值时是不能再次创建的,update_or_create方法,通过 user=user去找,如果存在就更新defaults的值,不存在就创建
18            return Response({'code'200'msg''登陆成功''token': token})
19        else:
20            return Response({'code'201'msg''用户名或密码错误'})
21
22# models.py
23class UserInfo(models.Model):
24    username = models.CharField(max_length=8)
25    password = models.CharField(max_length=8)
26
27
28class UserToken(models.Model):
29    token = models.CharField(max_length=32)
30    user = models.OneToOneField(to='UserInfo',on_delete=models.CASCADE)  
31    # django2版本,必须要加on_delete参数
32
33# urls.py
34
35from django.urls import path,include
36from rest_framework.routers import SimpleRouter
37from app01 import views
38
39# 实例化出一个对象
40routes = SimpleRouter()
41routes.register('user',views.Login,'login')  # 第一个参数是前缀,第二个参数是视图,第三个参数是别名,用做反向解析
42
43urlpatterns = [
44    path('admin/', admin.site.urls),
45    path('', include(routes.urls)),
46]

1.2认证功能代码

 1-第一步:写一个认证类,继承BaseAuthentication,重写authenticate  方法
2
3from rest_framework.authentication import BaseAuthentication
4from app01 import models
5from rest_framework.exceptions import AuthenticationFailed
6
7
8class BookAuth(BaseAuthentication):
9    def authenticate(self, request):
10        -第二步:在 authenticate 方法中判断用户是否登录(取出用户携带的token,去判断)
11        # request.query_params.get('token')  # 获取?后面的数据(相当于request.GET)
12        # 获取请求头中的数据  request.META 请求头中的一些数据,django会将传入的变量名变成HTTP_变量名(大写)
13        mytoken = request.META.get('HTTP_TOKEN')
14        user_token = models.UserToken.objects.filter(token=mytoken).first()
15        if user_token:
16             -第三步:如果认证通过,返回两个值,如果认证不通过抛异常
17            -# 在后续的request对象中,有这两个值,第一个给了request.user,第二个值给了request.auth
18            return user_token.user, mytoken
19        else:
20            raise AuthenticationFailed('请先登录')
21
22
23-第四步:把写的认证类,配置在视图类中(跟请求和响应的配置一样),全局配置
24# 全局配置
25REST_FRAMEWORK = {
26    'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.BookAuth']
27
28}
29
30# 局部配置
31authentication_classes = [BookAuth]
32
33优先级:局部>全局>默认
34'''
35在后续的request对象中,可以通过request.user获取当前用户对象,request.auth获取token值
36'''

2、权限

 1# 认证的使用
2    -第一步:写一个认证类,继承BaseAuthentication,重写authenticate  方法
3    -第二步:在 authenticate 方法中判断用户是否登录(取出用户携带的token,去判断)
4    -第三步:如果认证通过,返回两个值,如果认证不通过抛异常
5        -# 在后续的request对象中,有这两个值,第一个给了request.user,第二个值给了request.auth
6    -第四步:把写的认证类,配置在视图类中(跟请求和响应的配置一样),全局配置
7
8
9 可以给不同用户开设访问权限   
10from rest_framework.permissions import BasePermission
11
12# 超级会员
13class BookPermission(BasePermission):
14    def has_permission(self, request, view):  # 重写 has_permission方法
15        permiss_type = request.user.permiss_type  # 获取当前用户权限
16        if permiss_type in [2]:
17            return True
18        else:
19            return False
20
21
22# 普通会员
23class Book1Permission(BasePermission):
24    def has_permission(self, request, view):
25        permiss_type = request.user.permiss_type
26        if permiss_type in [1,2]:
27            return True
28        else:
29            return False
30
31
32# 全局配置
33    'DEFAULT_PERMISSION_CLASSES': ['app01.auth.BookPermission'],  # 权限
34# 局部配置
35    permission_classes = [Book1Permission]

3、频率

 1# 限制访问次数(按ip限制或者用户)
2获取ip或者用户
3request.META.get("REMOTE_ADDR")  # 获取客户端Ip地址
4request.user.id  # 获取用户id号
5
6from rest_framework.throttling import SimpleRateThrottle
7class BookThrot(SimpleRateThrottle):
8    scope = 'myscope'  # 必须写这个scope,名字可自定义
9    def get_cache_key(self, request, view):
10        # 返回什么就以什么做限制,获取客户端Ip地址request.META.get('REMOTE_ADDR')
11        return request.META.get('REMOTE_ADDR')
12
13# 全局配置
14'DEFAULT_THROTTLE_RATES': {
15        'myscope''3/m',  # key:'myscope' 对应频率类的scope属性,value;3/m,一分钟访问3次
16    },
17    'DEFAULT_THROTTLE_CLASSES': ['app01.auth.BookThrot'],
18# 局部配置
19    throttle_classes = []  # 局部(频率)
posted @ 2022-01-04 11:34  一叶松  阅读(67)  评论(0编辑  收藏  举报