(1)model层
class UserInfo(models.Model):
name = models.CharField(max_length=32)
# 写choice
user_choice = ((0, '普通用户'), (1, '会员'), (2, '超级用户'))
# 指定choice,可以快速的通过数字,取出文字使用get_user_type_display()
user_type = models.IntegerField(choices=user_choice, default=0)
pwd = models.CharField(max_length=32)
# 用户token
class UserToken(models.Model):
token = models.CharField(max_length=64)
user = models.OneToOneField(to=UserInfo)
(2)新建认证类(验证通过return两个参数)
from app01 import models
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
# 用drf的认证,写一个类
class LoginAuth(BaseAuthentication):
# 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象
def authenticate(self, request):
# 从request对象中取出token(也可以从其它地方取)
token = request.query_params.get('token')
# 去数据库过滤,查询
ret = models.UserToken.objects.filter(token=token).first()
if ret:
# 能查到,说明认证通过,返回空
# ret.user就是当前登录用户对象
return ret.user, ret
# 如果查不到,抛异常
raise exceptions.APIException('您认证失败')
(3)view层
from django.shortcuts import render
from rest_framework.views import APIView
from app01 import models
from django.core.exceptions import ObjectDoesNotExist
import hashlib
import time
from django.http import JsonResponse
from app01 import MySerializer
from rest_framework import exceptions
def get_token(name):
# 生成一个md5对象
md5 = hashlib.md5()
# 往里添加值,必须是bytes格式
# time.time()生成时间戳类型,转成字符串,再encode转成bytes格式
md5.update(str(time.time()).encode('utf-8'))
md5.update(name.encode('utf-8'))
return md5.hexdigest()
class Login(APIView):
#-局部禁用,在视图类中加一行:
authentication_classes = []
def post(self, request, *args, **kwargs):
response = {'status': 100, 'msg': '登录成功'}
name = request.data.get('name')
pwd = request.data.get('pwd')
try:
user = models.UserInfo.objects.get(name=name, pwd=pwd)
# 校验通过,登录成功,生成一个随机字符串(身份标识)token
token = get_token(name)
# 保存到数据库
# update_or_create更新或者创建
models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
response['token'] = token
except ObjectDoesNotExist as e:
response['status'] = 101
response['msg'] = '用户名或密码错误'
except Exception as e:
response['status'] = 102
# response['msg']='未知错误'
response['msg'] = str(e)
return JsonResponse(response, safe=False)
from rest_framework.request import Request
from app01.MyAuth import LoginAuth
class Books(APIView):
#-局部使用,在视图类中加一行:
# 列表中,类名不能加括号
# authentication_classes = [LoginAuth, ]
def get(self, request, *args, **kwargs):
# 只要通过认证,就能取到当前登录用户对象
print(request.user)
response = {'status': 100, 'msg': '查询成功'}
ret = models.Book.objects.all()
book_ser = MySerializer.BookSerializer(ret, many=True)
response['data'] = book_ser.data
return JsonResponse(response, safe=False)
-全局使用
-在setting中配置:
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',]
}