一、认证组件
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、
2、
3、
三、频率组件
1、
2、
3、