重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
使用步骤:
专注于为中小企业提供网站设计、网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业南平免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千余家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
# 通过认证类完成,使用步骤
1 写一个认证类,继承BaseAuthentication
2 重写authenticate方法,在内部做认证
3 如果认证通过,返回2个值
4 认证不通过抛AuthenticationFailed异常
5 只要返回了两个值,在后续的request.user 就是当前登录用户
认证源码分析:
https://www.cnblogs.com/suncolor/p/.html
认证组件的使用:
1.models.py中编写模型类
# 用户表
class User(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
def __str__(self):
return self.username
# 用户登录记录表
# 如何区分用户是否登录了?
class UserToken(models.Model):
# SET_NULL SET_DEFAULT CASCADE SET(函数内存地址)
user = models.OneToOneField(to='User', on_delete=models.CASCADE)
token = models.CharField(max_length=32, null=True) # 用户如果没有登录,就是空,如果登录了,就有值,登录多次以最后一次为准
2.views.py中判断登录信息
class UserView(ViewSet):
authentication_classes = []
@action(methods=['POST', ], detail=False, url_path='login')
def login(self, request):
# 取出前端传入的用户名密码,校验,通过,返回登录成功,失败就返回用户名密码错误
username = request.data.get('username')
password = request.data.get('password')
user = User.objects.filter(username=username, password=password).first()
if user:
# 登录成功,不同人生成的token是不一样的,谁登录的,就把token存到UserToken表中
token = str(uuid.uuid4()) # 生成一个永不重复的随机字符串
# 存UserToken:如果没有记录,就是新增,如果有记录更新一下即可
# 通过user去UserToken表中查数据,如果能查到,使用defaults的数据更新,如果查不到,直接通过user和defaults的数据新增
UserToken.objects.update_or_create(defaults={'token': token}, user=user)
# 作用是为了添加数据时防止重复. 先去查询, 如果没有在创建, 如果有则更新.
return Response({'code': 100, 'msg': '登录成功', 'token': token})
else:
return Response({'code': 101, 'msg': '用户名或密码错误'})
# 在app中写一个认证类 app_auth.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01.models import UserToken
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
# 认证逻辑,如果认证通过,返回两个值
#如果认证失败,抛出AuthenticationFailed异常
token=request.GET.get('token')
if token:
user_token=UserToken.objects.filter(token=token).first()
# 认证通过
if user_token:
return user_token.user,token
else:
raise AuthenticationFailed('认证失败')
else:
raise AuthenticationFailed('请求地址中需要携带token')
# 可以有多个认证,从左到右依次执行
# 全局使用,在setting.py中配置
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}
# 局部使用,在视图类上写
authentication_classes=[MyAuthentication]
# 局部禁用
authentication_classes=[]
认证的配置
# 可以有多个认证,从左到右依次执行
# 全局使用,在setting.py中配置自己写的认证类
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
}
# 局部使用,在视图类上写自己定义的认证类
authentication_classes=[MyAuthentication]
# 局部禁用
authentication_classes=[]