rest_framework之认证与权限 token不存数据库认证
1. 认证 :
介绍:
UserInfo表包含name , pwd , user_type三个字段
UserToken表包含token与user(关联UserInfo表) 当用户登录成功将随机字符串写入token, 并且将其返回给前台 当用户访问需要登录的视图需要将token拼到url中 , 如
http://127.0.0.1:8000/books/1?token=fbc4092d-b872-4b23-b2f7-29177ece9208
在自定义认证类里取到url的token, 与数据库的对比
源码分析
APIView---dispatch---initialize_request(包装request)---apiview的get_authenticators---
---将对象列表返回给authenticators----执行apiview的initial方法
---执行apiview的perform_authentication方法-----(request.user)
---Request.user方法----执行request对象的_authenticate方法------
循环request对象的authenticators----执行循环出的每个对象的authenticate方法,
将自己和request这个对象传入----最后返回一个元组(认证通过)
或者抛出异常(认证失败)exceptions.APIException--
--如果认证通过self.user, self.auth = user_auth_tuple执行的结果解压赋值,给request对象添加二个属性。
使用实例:
1. 自定义一个认证类
注意:这个类要放在单独的py文件中,(如果放在view中,全局配置无法使用)
class LoginAuth():
# 函数名一定要叫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就是当前登录用户对象,一旦retrun了,后面的认证类都不执行了
return ret.user,ret
# 如果查不到,抛异常
raise exceptions.APIException('您认证失败') 2. 视图类中使用
- 局部使用
在视图类中加一行:
authentication_classes = [LoginAuth, ]
- 全局使用
在setting中配置
REST_FRAMEWORK={
'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',]
}
中括号里的就是能导到认证类的东西
局部禁用
在视图类中加一行:
authentication_classes = []
2. 权限
用法介绍
在自定义权限类里判断用户类型, 如果是3(超级会员)则权限足够, 返回Ture
如果权限不够返回False
代码实例
1. 自定义一个权限类
class UserPermission():
# message是出错显示的中文
message='您没有权限查看'
def has_permission(self, request, view):
user_type = request.user.user_type
if user_type == 3:
return True
else:
return False 2. 使用
-局部使用
-在视图类中加一行:
permission_classes = [UserPermission, ] -全局使用
-在setting中配置
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.UserPermission',]
}
-局部禁用
-在视图类中加一行:
-permission_classes = []
choice
choice的用法:
-拿出数字对应的中文:get_字段名_dispaly()
====================================
认证组件的源码分析
执行到APIVIEW里面的dispatch方法 , 里面有一句
request = self.initialize_request(request, *args, **kwargs)
这一句会生成一个request对象,
生成这个对象的参数有
django的request对象,
authenticators=self.get_authenticators(),
这里的结果是authentication_classes列表里面的类实例化出来的一个个对象 然后会执行到self.initial(request, *args, **kwargs)这里
点进去里面有一句self.perform_authentication(request), 这个就是认证的 --------------------------------------------------------------------
| 分界线 上面的self代表视图类的对象 下面是Request的对象 |
-------------------------------------------------------------------- 点进去里面调用了request.user, 这是一个包装过的方法, 在rest_framework.request.Request中
再进去lou一眼,里面有self._authenticate()方法,再点进去
里面会循环第六行里面的对象列表, 调用每个对象的authenticate(self)方法, 注意!!!这里其实传了两个参数,
第一个是对象调用方法自动将自己传过去了,
第二个参数是request对象
源码里面会有两个变量来接收他的返回值,所以authenticate里面我们要返回两个值
总结:
综上, 所以我们需要在需要认证的视图类里面加上叫做authentication_classes
的列表, 列表里面放入我们自定义的认证类
自定义认证类的时候里面需要加上方法def authenticate(self, request):
,并且返回两个值
在源码中这个方法被try了, 捕获的异常是exceptions.APIException
, 所以如果认证失败抛出APIException
这个异常
认证的token不存到数据库
每个用户登录都会往数据库里写一条数据,然后每次访问需要登录的地址时都要去数据库检查一下token, 这对数据库的压力比较大
现提供一种方法不往数据库写token验证
用户登陆成功以后用自己的方式加密一下用户的id
我用的是
"吃葡萄不吐葡萄皮 id 不吃葡萄倒吐葡萄皮"用md5加密,后面再拼上"|id"
将这个字符串作为token返回给前台
然后访问其他的需要登录的页面时url里拼上这个就好了
例如,: id为1的用户登录了, 生成一个7f38e7a645fbd1b3c68fbc75ecd62d24|1
字符串
id为2的用户登录了, 生成一个a07687f76d66557e59db18bd89910e3a|2
字符串
访问其他页面时带上这个字符串,例如访问书本详情时的url为:
http://127.0.0.1:8000/books/1?token=a07687f76d66557e59db18bd89910e3a|2
token翻译成明文就是吃葡萄不吐葡萄皮2不吃葡萄倒吐葡萄皮|2
在认证里面通过 " | " 切分取到id , 再通过上面的加密方式生成token与url里面的进行对比
代码示例:
获取加密字符串的函数
import hashlib
def get_token(id):
md5=hashlib.md5()
md5.update('吃葡萄不吐葡萄皮'.encode('utf-8'))
md5.update(str(id).encode('utf-8'))
md5.update('不吃葡萄倒吐葡萄皮'.encode('utf-8'))
return md5.hexdigest() 登录成功以后生成token:
token = methord.get_token(user.id)+'|'+str(user.id) 认证类
class LoginAuth:
def authenticate(self, request):
token = request.GET.get('token')#获取url的token
id = token.split('|')[1]#拿到id
re_token = methord.get_token(id) + '|' + str(id)#根据我的加密方式进行加密
if token == re_token:#判断url的token是否正确
user=models.UserInfo.objects.filter(pk=int(id)).first()
return user,user
else:
raise APIException('还没登录')
rest_framework之认证与权限 token不存数据库认证的更多相关文章
- restframework 认证、权限、频率组件
一.认证 1.表的关系 class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField( ...
- rest_framework 认证与权限
一 认证 1.1先写个类(认证组件) from app01 import models from rest_framework import exceptions from rest_framewo ...
- rest_framework组件之认证,权限,访问频率
共用的models from django.db import models # Create your models here. class User(models.Model): username ...
- drf token刷新配置、认证组件(使用)、权限组件(使用)、频率组件(使用)、异常组件(使用)
目录 一.特殊路由映射的请求 二.token刷新机制配置(了解) 三.认证组件项目使用:多方式登录 1.urls.py 路由 2.views.py 视图 3.serializers.py 序列化 4. ...
- 权限认证 cookie VS token
权限认证 cookie VS token 我前公司的应用都是 token 授权的,现公司都是维护一个 session 确认登录状态的.那么我在这掰扯掰扯这两种权限认证的方方面面. 工作流程 先说 co ...
- Rest_Framework之认证、权限、频率组件源码剖析
一:使用RestFramwork,定义一个视图 from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet ...
- rest_framework 认证组件 权限组件
认证组件 权限组件 一.准备内容 # models class User(models.Model): name = models.CharField(max_length=32) pwd = mod ...
- Django框架rest_framework中APIView的as_view()源码解析、认证、权限、频率控制
在上篇我们对Django原生View源码进行了局部解析:https://www.cnblogs.com/dongxixi/p/11130976.html 在前后端分离项目中前面我们也提到了各种认证需要 ...
- DRF之版本控制、认证和权限组件
一.版本控制组件 1.为什么要使用版本控制 首先我们开发项目是有多个版本的当我们项目越来越更新,版本就越来越多,我们不可能新的版本出了,以前旧的版本就不进行维护了像bootstrap有2.3.4版本的 ...
随机推荐
- 850. Dijkstra求最短路 II
给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值. 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1. 输入格式 第一行包含整数n和m. 接下来m行每行包 ...
- 《自动化平台测试开发-Python测试开发实战》第2次印刷
书籍货源比较紧张.紧张啊,如此短的时间,已经第2次印刷.第2次印刷. 第2次印刷. 同时该书已确认与台湾出版社合作翻译成繁体版,甚至有可能与国外出版社合作翻译成英文版. 2018年7月 第1次印刷 2 ...
- [JS奇怪的世界]No.55 危險小叮嚀:陣列與for in
前言 前面已經瞭解了使用內建函數建構子的某些危險地方,但其實陣列與for in,也是有一些危險的地方. 陣列與for in 在前面幾個章節有講過陣列就是物件,所以我們一樣可以使用 for in來做處理 ...
- http 详解
HTTP协议中GET.POST和HEAD的介绍 GET: 请求指定的页面信息,并返回实体主体. HEAD: 只请求页面的首部. POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体 ...
- 使用python抓取美团商家信息
抓取美团商家信息 import requests from bs4 import BeautifulSoup import json url = 'http://bj.meituan.com/' ur ...
- 怎样解决使用feof()函数时出现的问题?
feof函数 昨天在做一个课程设计时,一个函数的功能是将文件中的数据一条条的读到链表中去.既然不确定有多少条数据,那只能借助feof()函数了,本来文件部分就没学好,也就知道这一个方法. ...
- Newman+Jenkins实现接口自动化测试
目录 一.是什么Newman 二.如何安装 三.如何使用 1.运行本地文件 2.运行在线文件 3.以node.js库运行 4.导出报告 四.命令行测试真实接口 1.导出collection文件 2.导 ...
- idea导入 spring framework项目
准备的环境:gradle,idea 注意:gradle版本不一致会报各种错误,那么怎么查找依赖的版本呢? 首先在git上把spring framework项目拉取下来, 步骤一:复制URL路径 步骤二 ...
- SPA那点事
前端猿一天不学习就没饭吃了,后端猿三天不学习仍旧有白米饭摆于桌前.IT行业的快速发展一直在推动着前端技术栈在不断地更新换代,前端的发展成了互联网时代的一个缩影.而单页面应用的发展给前端猿分了一杯羹. ...
- localstorage浏览器储存
需求 a.html页面生成订单信息,b.html中调用. 通过不操作数据库,直接在浏览器自带的数据库中进行操作,当然主要是对Json数据的操作. a.html代码部分: <!--html--&g ...