认证简介

使用场景:有些接口在进行访问时,需要确认用户是否已经登录,比如:用户需要购买物品时,在结账的时候,就需要进行登录验证的。

用户认证RBAC(Role-Based Access Control)

一般用户认证都是基于角色认证:

  • 三表机制

    • 用户表(User)
    • 角色表(Group)
    • 权限表(Permission)

    用户表关联角色表,角色表关联权限表

  • 五表机制

    • 用户表(User)
    • 用户角色关系表(User-Group)
    • 角色表(Group)
    • 角色权限表(Group-Permission)
    • 权限表(Permission)

    用户表与角色表多对多、角色表与权限表多对多

  • Django采用六表机制

    • 用户表(User)
    • 用户角色关系表(User-Group)
    • 角色表(Group)
    • 角色权限表(Group-Permission)
    • 权限表(Permission)
    • 角色权限表(User-Permission)

    用户表与角色表多对多、角色表与权限表多对多、用户表和权限表多对多

局部使用

  • models.py
from django.contrib.auth import models

class User(models.Model):
username=models.CharField(max_length=32)
password=models.CharField(max_length=32)
user_type=models.IntegerField(choices=((1,'超级用户'),(2,'普通用户'),(3,'二B用户'))) class UserToken(models.Model):
user=models.OneToOneField(to='User')
token=models.CharField(max_length=64)
  • 自定义认证类
from rest_framework.authentication import BaseAuthentication

class TokenAuth():
def authenticate(self, request):
token = request.GET.get('token')
token_obj = models.UserToken.objects.filter(token=token).first()
if token_obj:
return
else:
raise AuthenticationFailed('认证失败') def authenticate_header(self,request):
pass
  • views.py
def get_random(name):
import hashlib
import time
md=hashlib.md5()
md.update(bytes(str(time.time()),encoding='utf-8'))
md.update(bytes(name,encoding='utf-8'))
return md.hexdigest() class Login(APIView):
def post(self,reuquest):
back_msg={'status':1001,'msg':None}
try:
name=reuquest.data.get('name')
pwd=reuquest.data.get('pwd')
user=models.User.objects.filter(username=name,password=pwd).first()
if user:
token=get_random(name)
models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
back_msg['status']='1000'
back_msg['msg']='登录成功'
back_msg['token']=token
else:
back_msg['msg'] = '用户名或密码错误'
except Exception as e:
back_msg['msg']=str(e)
return Response(back_msg) class Course(APIView):
authentication_classes = [TokenAuth, ] def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')
  • 进阶:不存数据库的token验证

    def get_token(id,salt='123'):
    import hashlib
    md=hashlib.md5()
    md.update(bytes(str(id),encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))
    return md.hexdigest()+'|'+str(id) def check_token(token,salt='123'):
    ll=token.split('|')
    import hashlib
    md=hashlib.md5()
    md.update(bytes(ll[-1],encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))
    if ll[0]==md.hexdigest():
    return True
    else:
    return False class TokenAuth():
    def authenticate(self, request):
    token = request.GET.get('token')
    success=check_token(token)
    if success:
    return
    else:
    raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
    pass class Login(APIView):
    def post(self,reuquest):
    back_msg={'status':1001,'msg':None}
    try:
    name=reuquest.data.get('name')
    pwd=reuquest.data.get('pwd')
    user=models.User.objects.filter(username=name,password=pwd).first()
    if user:
    token=get_token(user.pk)
    # models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
    back_msg['status']='1000'
    back_msg['msg']='登录成功'
    back_msg['token']=token
    else:
    back_msg['msg'] = '用户名或密码错误'
    except Exception as e:
    back_msg['msg']=str(e)
    return Response(back_msg) from rest_framework.authentication import BaseAuthentication class TokenAuth():
    def authenticate(self, request):
    token = request.GET.get('token')
    token_obj = models.UserToken.objects.filter(token=token).first()
    if token_obj:
    return
    else:
    raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
    pass class Course(APIView):
    authentication_classes = [TokenAuth, ] def get(self, request):
    return HttpResponse('get') def post(self, request):
    return HttpResponse('post')

总结:局部使用,只需要在视图类里加入:

authentication_classes = [TokenAuth, ]

全局使用

全局使用需要在setting.py中进行配置

REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}

源码分析

# Request对象的user方法

@property
def user(self):
"""
Returns the user associated with the current request, as authenticated by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user def _authenticate(self):
"""
Attempt to authenticate the request using each authentication instance
in turn.
"""
for authenticator in self.authenticators:
try:
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
return self._not_authenticated() def _not_authenticated(self):
"""
Set authenticator, user & authtoken representing an unauthenticated request.
Defaults are None, AnonymousUser & None.
"""
self._authenticator = None
if api_settings.UNAUTHENTICATED_USER:
self.user = api_settings.UNAUTHENTICATED_USER()
else:
self.user = None if api_settings.UNAUTHENTICATED_TOKEN:
self.auth = api_settings.UNAUTHENTICATED_TOKEN
()
else:
self.auth = None
# self.authenticators
def get_authenticators(self):
return [auth() for auth in self.authentication_classes]

认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类

drf--认证组件的更多相关文章

  1. drf认证组件、权限组件、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  2. DRF认证组件

    1.DRF认证组件之视图注册用法(自定义简单使用) settings.py配置 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.a ...

  3. drf认证组件(介绍)、权限组件(介绍)、jwt认证、签发、jwt框架使用

    目录 一.注册接口 urls.py views.py serializers.py 二.登录接口 三.用户中心接口(权限校验) urls.py views.py serializers.py 四.图书 ...

  4. DRF认证组件流程分析

    视图函数中加上认证功能,流程见下图 import hashlib import time def get_random(name): md = hashlib.md5() md.update(byte ...

  5. Django框架之DRF 认证组件源码分析、权限组件源码分析、频率组件源码分析

    认证组件 权限组件 频率组件

  6. DRF框架(六)——三大认证组件之认证组件、权限组件

    drf认证组件 用户信息表 from django.db import models from django.contrib.auth.models import AbstractUser class ...

  7. 【DRF认证】

    目录 认证组件的详细用法 本文详细讲述了DRF认证组件的原理以及用法. @ * 源码剖析** 上一篇博客讲解DRF版本的时候我们都知道了,在dispatch方法里执行了initial方法来初始化我们的 ...

  8. drf视图组件、认证组件

    视图组件 1.基本视图 url(r'^publish/$', views.PublishView.as_view()), url(r'^publish/(?P<pk>\d+)/$', vi ...

  9. DRF框架之认证组件用法(第四天)

    1. 什么是drf 框架的认证组件: auth 就等于是jango中的Auth模块,Auth是自带session信息,但是 drf的认证组件可以自定义token携带过去,去判断用的 2.如何实现认证呢 ...

  10. DRF 之 认证组件

    1.认证的作用? 我们知道,当我们在网站上登陆之后,就会有自己的个人中心,之类的可以对自己的信息进行修改.但是http请求又是无状态的,所以导致我们每次请求都是一个新的请求,服务端每次都需要对请求进行 ...

随机推荐

  1. Java的修饰、继承、接口、抽象类

     1.private 修饰属性或者方法,只能在本类中被访问,定义后需要加get()set()方法,这样提高数据的安全性 私有属性虽然不能直接访问,但是其对象 或者 子类对象可以通过公有方法进行设值和获 ...

  2. 9-3 deepsort在win10配置

    win10+python3.5+tensorflow https://blog.csdn.net/Draw_1999/article/details/79735677 deep-sort https: ...

  3. Ql004(母牛的故事)

    一,看题目 1,这个虽然我不想说,但是我确实不会,但是我的意思是你可以不会但是不能每次都不会那咋办? 二,看题解 1,你得大概知道这个东西是考啥的(虽然这个东西提前给你说了是d递归),但是考试肯定没人 ...

  4. OD(lfdnb)

    由于一场意外,D死了,在此开一个新坑 2019.11.13 考前焦虑 智商为负 有点担心考试状态 2019.11.12 上午考试简直心态爆炸 T1看了一个小时不会 然后看T2,这时候wxy聚聚已经切了 ...

  5. 如何确定假设检验的样本量(sample size)?

    在<如何计算假设检验的功效(power)和效应量(effect size)?>一文中,我们讲述了如何根据显著性水平α,效应量和样本容量n,计算功效,以及如何根据显著性水平α,功效和样本容量 ...

  6. 【组合数学】【P5520】[yLOI2019] 青原樱

    A [yLOI2019] 青原樱 Background 星川之下皆萤火尘埃 我独行在人潮你天真而待 相遇若是借丹青着色 青原上 绯樱如海 --银临<青原樱>(Cover 人衣大人) Des ...

  7. 食物链【NOI2001】(信息学奥赛一本通 1390)

    [题目描述] 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种 ...

  8. python总结八

    1.range的使用讲解: 首先呢如果只是一个参数的话,那么就是循环遍历这个参数递增,例如 range(5)>>[1,2,3,4] 如果是两个参数的话,且注意后面的第二个参数要比第一个大, ...

  9. 【技术博客】Postman接口测试教程 - 环境、附加验证、文件上传测试

    Postman接口测试教程 - 环境.附加验证.文件上传测试 v1.0 作者:ZBW 前言 继利用Postman和Jmeter进行接口性能测试之后,我们发现Postman作为一款入门容易的工具,其内置 ...

  10. 《Modern PHP》读书笔记

    这本书适合你吗?     我认为每个有一定PHP开发经验的人都应该读读这本书,因为正如书中的前言所说: “网上有成千上万的PHP教程,其中大多数都已经过时了,展示的是陈旧的实践方式.可是,谷歌的搜索结 ...