认证组件 权限组件
一、准备内容
# models
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
user_type = models.IntegerField(choices=((1, "超级管理员"), (2, "普通管理员"), (3, "2b用户")), default=3)
# 跟User表做一对一关联
class Token(models.Model):
user = models.OneToOneField(to='User')
token = models.CharField(max_length=64)
二、认证逻辑
# MyAuths.py 自定义认证逻辑代码
class MyAuth(BaseAuthentication):
def authenticate(self, request):
# 写认证的逻辑
token = request.GET.get('token')
token_obj = models.Token.objects.filter(token=token).first()
if token_obj:
# 能够取到值,表示已经登录了
print("验证登录通过")
return token_obj.user, token_obj
else:
# 没有取到值,表示没有登录,往外抛异常
raise AuthenticationFailed('还没有登录呦')
# views.py 视图部分逻辑
from rest_framework.views import APIView
from app01 import models
import uuid # 用来生成唯一token
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.response import Response
from app01.MyAuths import MyAuth
# Create your views here.
class Books(APIView):
# 局部认证, 源码中的 authentication_classes 部分,执行列表中的认证逻辑
# 执行优先级为:最高是此处定义的视图类中定义的 ---> 如果没有,就去项目settings.py中查找 ---> 都没有就选择rest_framework默认的配置文件中取
authentication_classes = [MyAuth, ]
def get(self, request):
# request.user 就是当前登录用户
print(request.user.name) # 'AnonymousUser' object has no attribute 'name'
# 上面语句后面的错误,是因为原先将 authentication_classes = [MyAuth, ] 这句代码放进了get方法里面了
# print(request.user.name, type(request.user))
return Response('这个是验证过登录而返回的的信息!')
class Login(APIView):
def post(self, request):
response = {'code': 100, 'msg': '登录成功'}
name = request.data.get('name')
pwd = request.data.get('pwd')
try:
user = models.User.objects.filter(name=name, pwd=pwd).get()
# 登录成功,需要将token写进token表中
# 生成一个唯一的token id
token = uuid.uuid4()
models.Token.objects.update_or_create(user=user, defaults={'token': token})
response['token'] = token
except ObjectDoesNotExist as e:
response['code'] = 101
response['msg'] = '用户名或者密码错误'
except Exception as e:
response['code'] = 102
response['msg'] = str(e)
return Response(response)
三、权限逻辑
# MyAuths.py 权限逻辑部分
class MyPermision(BasePermission):
message = '不是超级用户,查看不了'
def has_permission(self,request,view):
if request.user.user_type==1:
return True
else:
return False
# views.py 视图逻辑部分
class Publish(APIView):
# authentication_classes = [] 在setting.py里面设置了全局的token认证,
authentication_classes = [MyAuth, ]
permission_classes = [MyPermision, ]
def get(self, request):
# print(request.user.name)
return Response('返回了所有出版社信息')