认证简介

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

用户认证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. eslint的语法配置项

    其实我并不反对这些语法检测,但是像许多反个人意愿的那就真的不得不吐槽了,比如vue-cli脚手架创建的默认eslint规则: 代码末尾不能加分号 ; 代码中不能存在多行空行 tab键不能使用,必须换成 ...

  2. 中国网络安全行业分类及全景图2019H1

    中国网络安全行业分类及全景图2019H1   概述 中国网络安全行业分类及全景图: 一级分类包含了端点安全.网络安全.应用安全.数据安全.身份与访问管理和安全管理六个一级分类,这些一级分类分别对应了网 ...

  3. phpcms网站迁移无法更新内容提示Table 'led_com.lz_' doesn't exist的解决方法

    新接的一位客户说要把旧phpcms网站迁移到新的服务器并更换新域名,这对ytkah是小菜一碟,但往往事与愿违,忽略了一些细节会很惨的.进入新站后台怎么都无法生成内容,提示Table 'led_com. ...

  4. POJ1463-Strategic game-(树形dp)

    http://poj.org/problem?id=1463 题意:有一棵n个结点的树,要在这棵树上放士兵守卫,一个士兵可以守卫自己所在的位置以及与之相邻的点.问最少放多少个士兵? 题解:对于每个点, ...

  5. android开发环境sdk manager无法更新问题

    由于无法fq,也没有vpn,建议各位新手不用sdk manager去安装,直接下载bundle包,就不用去折腾各种开发环境了.推荐bundle下载地址:http://adt.android-studi ...

  6. Pandas | GroupBy 分组

    任何分组(groupby)操作都涉及原始对象的以下操作之一: 分割对象 应用一个函数 结合的结果 在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数.在应用函数中,可以执行以下操作: 聚 ...

  7. three.js 打包为一个组-几个单独的模型

    代码: <!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl ...

  8. 浅谈HTTPS传输过程

    HTTPS是什么 HTTPS不是一个新的协议,可以理解为是一个HTTP协议的加密"版本"(HTTP+SSL(TLS)).那为什么HTTP协议需要加密,不加密会出现什么问题呢?先来了 ...

  9. MySQL重要知识点

    可能是全网最好的MySQL重要知识点 |  mp.weixin.qq.com 点击蓝色“程序猿DD”关注我 回复“资源”获取独家整理的学习资料! 标题有点标题党的意思,但希望你在看了文章之后不会有这个 ...

  10. 《Linux就该这么学》培训笔记_ch07_RAID和LVM

    <Linux就该这么学>培训笔记_ch07_RAID和LVM 文章最后会post上书本的笔记照片. 文章主要内容: RAID(独立冗余磁盘阵列) 部署磁盘阵列 损坏磁盘阵列及修复 磁盘阵列 ...