一、认证组件
判断用户是否登录,数据库是否有值
1、需求:
通过认证组件去认证,没有认证通过的用户不让登录。认证方式前端发来的token值与数据库进行对比
2、models
from django.db import models class User(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) # 用户类型 user_type = models.IntegerField(choices=((1, '2B用户'), (2, '普通用户'), (3, '超级用户'))) # 一对一的关系 class UserToken(models.Model): token = models.CharField(max_length=64) # OneToOneField本质就是ForeignKey+unique user = models.OneToOneField(to=User, on_delete=models.CASCADE) # user = models.ForeignKey(to=User, unique=True,on_delete=models.CASCADE)
2、写一个认证 auth.py
from .models import UserToken from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class LoginAuth(BaseAuthentication): # 重写一下authenticate方法 def authenticate(self, request): token = request.query_params.get('token') # 从url中的参数去拿 print(token) #4d1455f4-97be-4cf6-88a1-dee6e21433ad user_token = UserToken.objects.filter(token=token).first() if user_token: return user_token.user, token else: raise AuthenticationFailed('您没有登录!')
3、views
class UserView(ViewSet): # authentication_classes = [] # 局部解除认证禁用,token没有认证通过就不让登录 permission_classes = [] # 局部解除权限禁用 @action(methods=['POST'], detail=False) # /user/login/ post 请求就会执行 def login(self, request, *args, **kwargs): # 前端传入用户名密码 username = request.data.get('username') password = request.data.get('password') user = User.objects.filter(username=username, password=password).first() print(user) if user: # 生成一个随机字符串,返回给前端,并且要把随机字符串存到token表中 token = str(uuid.uuid4()) ##### 方式一:麻烦方式 # user_token=UserToken.objects.filter(user=user).first() # if user_token: # user_token.token=token # user_token.save() # else: # UserToken.objects.create(user=user,token=token) ## 方式二:通过user去UserToken表中查,如果能查到用defaults的更新,如果查不到,就用user和defaults新增一条记录 # 每次登录会返回一个uuid,会更新uuid UserToken.objects.update_or_create(defaults={'token': token}, user=user) return Response({'code': 100, 'msg': '登录成功', 'token': token, 'username': user.username}) else: return Response({'code': 101, 'msg': '用户名或密码错误'})
补充:
1、继承 ViewSetMixin,APIView,常见的5个路由自动匹配,其他的通过action装饰器进行指定
4、开启认证
在全局开启认证时需要指定app01下面的auth认证模块
## 全局开启 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'app01.auth.LoginAuth' ], } ##局部开启 authentication_classes = [BasicAuthentication] ##局部禁用 authentication_classes = []
5、拿着数据库的token访问
127.0.0.1:8000/user/login/?token=730c7ebf-4b12-4f55-a337-0b341d333395
二、权限组件
判断登录成功后的用户是否有操作权限
1、permissions 文件
from rest_framework.permissions import BasePermission # 1 写一个类,继承 BasePermission # 2 重写 has_permission # 3 在方法中校验用户是否有权限,如果有,就返回True,如果没有,就返回False class UserPermission(BasePermission): def has_permission(self, request, view): # request 当次请求的request, 新的,它是在认证类之后执行的,如果认证通过了request.user 就是当前登录用户 # 拿到当前登录用户,查看它的类型,确定有没有权限 if request.user.user_type == 3: return True else: self.message = '您的用户类型是:%s,您没有权限操作' % (request.user.get_user_type_display()) return False
2、views
from rest_framework.viewsets import ViewSetMixin, ViewSet from rest_framework.response import Response from rest_framework.decorators import action from .models import User, UserToken import uuid # class UserView(ViewSetMixin,APIView): class UserView(ViewSet): # authentication_classes = [] # 局部解除认证禁用,token没有认证通过就不让登录 # permission_classes = [] # 局部解除权限禁用 @action(methods=['POST'], detail=False) # /user/login/ post 请求就会执行 def login(self, request, *args, **kwargs): # 前端传入用户名密码 username = request.data.get('username') password = request.data.get('password') user = User.objects.filter(username=username, password=password).first() print(username) if user: # 生成一个随机字符串,返回给前端,并且要把随机字符串存到token表中 token = str(uuid.uuid4()) ##### 方式一:麻烦方式 # user_token=UserToken.objects.filter(user=user).first() # if user_token: # user_token.token=token # user_token.save() # else: # UserToken.objects.create(user=user,token=token) ## 方式二:通过user去UserToken表中查,如果能查到用defaults的更新,如果查不到,就用user和defaults新增一条记录 # 每次登录会返回一个uuid,会更新uuid UserToken.objects.update_or_create(defaults={'token': token}, user=user) return Response({'code': 100, 'msg': '登录成功', 'token': token, 'username': user.username}) else: return Response({'code': 101, 'msg': '用户名或密码错误'})
3、开启权限认证
## 全局认证 REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'app01.permissions.UserPermission', ], } ## 局部认证 permission_classes = [BasePermission] ##局部解除权限认证 permission_classes = []
4、访问效果
三、频率组件
1、
2、
3、
标签:username,models,request,认证,token,user,组件,权限,drf From: https://www.cnblogs.com/dgp-zjz/p/17683304.html