django认证01---token
1.登录鉴权跟 Token 的鉴权区别
以 Django 的账号密码登录为例来说明传统的验证鉴权方式是怎么工作的,当我们登录页面输入账号密码提交表单后,会发送请求给服务器,服务器对发送过来的账号密码进行验证鉴权,验证鉴权通过后,把用户信息记录在服务器端( django_session 表中),同时返回给浏览器一个 sessionid 用来唯一标识这个用户,浏览器将 sessionid 保存在 cookie 中,之后浏览器的每次请求都一并将 sessionid 发送给服务器,服务器根据 sessionid 与记录的信息做对比以验证身份
Token 的鉴权方式就清晰很多了,客户端用自己的账号密码进行登录,服务端验证鉴权,验证鉴权通过生成 Token 返回给客户端,之后客户端每次请求都将 Token 放在 header 里一并发送,服务端收到请求时校验 Token 以确定访问者身份
session 的主要目的是给无状态的 HTTP 协议添加状态保持,通常在浏览器作为客户端的情况下比较通用。而 Token 的主要目的是为了鉴权,同时又不需要考虑 CSRF 防护以及跨域的问题,所以更多的用在专门给第三方提供 API 的情况下,客户端请求无论是浏览器发起还是其他的程序发起都能很好的支持。所以目前基于 Token 的鉴权机制几乎已经成了前后端分离架构或者对外提供 API 访问的鉴权标准,得到广泛使用
2.基于restframework 的用户验证跟 django 用户验证的区别
基于restframework 的用户验证跟 django 用户验证的区别 : django 用户验证只是基于 cookie 与 session 来完成的。而restframework还可以通过token 其中的问题就在于中间件的差距。 我现在访问我的 restf api 接口时可以看到浏览器会有一个登陆 ,这里通过 django 创建的 超级用户或者注册的用户就可以登陆 这是因为我们在 django 的url 中配置了 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 而 对应的 rest_framework.urls 有 包含 login 和 logout 两个url。 如果使用django会验证 csrf ,我们登陆时 django 返回的 html 中其实是包含一个 csrf 的 code 的,用来做表单的 安全验证的。(这是因为django默认打开 csrf 中间件,如果关闭了就不会校验csrf) 所以如果用户验证需要做成 restful api ,这个 自带的 login是无法拿来直接用的。
如果我们需要做成一个前后端分离的用户验证, 就需要通过其他的方法。 【Auth 模块】 django 的 MIDDLEWARE 中包含的以下两个 MIDDLEWARE 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 可以在一个 request 进来的时候,将request里的 cookie 里面的 session_id 转换成 我们的 user !!!!! 也就是我们之前看到的 request.user 。 我们现在需要配置 restful 的 MIDDLEWARE , 直接在 django 的 settings.py 里面添加 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ) } 官方文档显示 restful 提供的 auth 有三种 : BasicAuthentication 、 TokenAuthentication 、 SessionAuthentication 。 其中 : SessionAuthentication :跟django中的机制是一样的, 常用于浏览器, 因为浏览器会自动设置 cookie ,并将他的 cooike 和session 带到服务器, 所以前后端分离的系统用这种机制比较少见,但是还是可以做。 TokenAuthentication : 是需要重点关注的,使用他前 ,必须先将 'rest_framework.authtoken' 添加到 django 的 INSTALLED_APPS 中。 INSTALLED_APPS = ( ... 'rest_framework.authtoken' ) 这个 tokenauth 实际上会给我们创建一张表,凡是有表的 app 都要加入到 INSTALLED_APPS 中。 如果不加人,就不会帮我们生成这些表。 此时执行 migrate 进行数据迁移。 可以看到为我们生成了一张表,该表有一个外键指向我们的 UserProfile (用户信息)表。 一个用户对于一个 token 。 而我创建一个超级用户的时候,并没有在 authtoken_token 这张表里面给我添加一个对应的 token 。 这个 token 需要我们自己来创建 。创建方法如下 ,调用 Token 模块,将 user 传进去: from rest_framework.authtoken.models import Token token = Token.objects.create(user=...) print token.key 所以 当用户注册时保存了提交的 UserProfile 之后,调用这段代码,把保存的 UserProfile 传进去。 这样就会生成 token 。
而后端需要在 django 的 url 中配置 token 的url :
from rest_framework.authtoken import views urlpatterns += [ url(r'^api-token-auth/', views.obtain_auth_token) ]
现在可以通过向 http://127.0.0.1:8000/api-token-auth/ 这个url 发送 post 请求并且携带
{
"username":"admin",
"password":"admin123456"
}
这个方式来获取 token ,发送请求后,他会返回一个 token 。此时如果这个 UserProfile
没有对应的 key ,就会在 authtoken_token 这张表创建一条数据 ,并且关联到你提交的
用户 ,给他生成一个 key 。
前端如何使用这个 token ? 【把他放到 http 的 header 里面】
对于客户端进行身份验证,令牌密钥应该包含在AuthorizationHTTP头中。关键字应以字符串文字“Token”为前缀,用空格分隔两个字符串。例如:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
此时我在我的 url 请求的头部添加这个之后,访问我的 restful api 资源了后台获取到这个 token 后
还不能解析出这个 token 对应的用户是谁,我们需要在 REST_FRAMEWORK 里添加
'rest_framework.authentication.TokenAuthentication',
才能解析出对应的用户 。
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
)
}
此时需要知道用户传递过来的 token 是什么 ,直接通过 request.auth 就可以看到。
完成 上面两步,就可以访问我的 restful api 资源了。
(以前需要登录,现在只要头部包含 这个 token 就可以访问。)
如果用户在 token 过期的情况下访问公共url , 就会报错, 这个问题前端也可以解决,后端的解决方案是, 把这个 token 验证不放在 settings.py 里做全局验证, 只对部分接口做验证。
把 REST_FRAMEWORK 中下面这个
1. 'rest_framework.authentication.TokenAuthentication',
注释掉 ,
2.在需要做验证的视图那里 导入
from rest_framework.authentication import TokenAuthentication
然后在视图里添加 authentication_classes 属性。 因为要给他个元组, 所以记得用逗号
authentication_classes = (TokenAuthentication, )
这个 token 的缺点是 :
1.这个token 是保存在服务器里面的。
如果我们是一个分布式系统,有两套子系统想要使用同一个认证系统,他就会出现问题,
因为他的 token 是放在某一台服务器的,如果是分布式的,那我们还得将这些用户同步过去。
2.这个 toen 是没有过期时间的,永久有效,一旦泄露了别人就可以一直用。
2 django中实现token:引入DRF 框架
注意DRF框架是基于django,也就是说使用DRF包就必须安装django。所以文件结构和django一样,可以混用:既开发django也开发djangorestframework。 setting中的配置:REST框架API的任何全局设置都保存在一个名为REST framework的配置字典中。与django不冲突。 当我们用浏览器访问rest_framework 的应用时REST framework的配置生效,而我们访问我们正常的django的app时django的配置生效。注意这里都是全局配置 尤其是对应中间件的配置,和项目目录下的url文件息息相关。
正常情况下我们会引入:
'rest_framework',而我们现在只需要认证功能 rest_framework.authtoken
在配置中加入TokenAuthentication,也就是通过token 我们就可以直接从request 中取出user(这就是中间件的好处)取出user意味着登陆状态
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
)
}
setting文件 REST_FRAMEWORK 配置:https://www.django-rest-framework.org/ (中间件)
DEFAULT_AUTHENTICATION_CLASSES
身份验证类的列表或元组,用于确定访问request.user或request.auth属性时使用的默认验证器集。 默认: (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
)
DEFAULT_PERMISSION_CLASSES
权限类的列表或元组,用于确定在视图开头检查的默认权限集。必须由列表中的每个类授予权限。
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
'rest_framework.permissions.IsAdminUser',(仅管理员可以访问DRF的所有url)
'rest_framework.permissions.IsAuthenticated', #必须有(必需认证过才能访问DRF所有url)
默认:
( 'rest_framework.permissions.AllowAny', ) PAGE_SIZE
用于分页的默认页面大小。如果设置为None
,则默认情况下禁用分页。
使用:
配置所有,
sender指定settings.AUTH_USER_MODEL
设置每次新生成用户时,自动生成token的signals。
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token # 为每个用户添加token验证
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
.__init__.py 将它放在models.py文件中的任何地方,它将在Django线程启动时注册(__init__.py也是可以的)
from .signals import create_auth_token
sender指定实体
from django.contrib.auth.models import User
@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
在view中进行token验证
没有就创建并且取出token,有就直接取出token
token, created = Token.objects.get_or_create(user=user)
虽然在django设置文件中指定了REST_FRAMEWORK设置,但是基于函数的视图需要@api_view装饰器,否则,根本不执行令牌认证
django自带app和django_rest_framework的区别:
from rest_framework.decorators import api_view @api_view(['POST','GET'])
def my_view(request):
if request.user.is_authenticated():
...
过期时间:
https://www.cnblogs.com/hello-/articles/9090786.html
https://www.jianshu.com/p/078fb116236e
3.django中实现:JWT
django认证01---token的更多相关文章
- django 认证系统--3
WEB request中的认证 django使用sessions和middleware和reqeust对象联系在一起 它们通过给每一个reqeust请求添加一个request.user属性来代表当前用 ...
- 应用JWT进行用户认证及Token的刷新
本文将通过实际的例子来演示如何在ASP.NET Core中应用JWT进行用户认证以及Token的刷新方案(ASP.NET Core 系列目录) 一.什么是JWT? JWT(json web token ...
- ASP.NET Core 2.2 : 二十六. 应用JWT进行用户认证及Token的刷新
来源:https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_26.html 本文将通过实际的例子来演示如何在ASP.NET Core中应用JWT进行用户认证以及T ...
- Django框架01 / http协议、web框架本质
Django框架01 / http协议.web框架本质 目录 Django框架01 / http协议.web框架本质 1.http协议 1.1 http协议简介 1.2 什么是http协议 1.3 H ...
- Django认证系统并不鸡肋反而很重要
在使用django-admin startproject创建项目后,Django就默认安装了一个采用session实现的认证系统.这是Django相比于其他框架的一大特点:自带认证系统,开箱即用.有人 ...
- 自定义Django认证系统的技术方案
Django已经提供了开箱即用的认证系统,但是可能并不满足我们的个性化需求.自定义认证系统需要知道哪些地方可以扩展,哪些地方可以替换.本文就来介绍自定义Django认证系统的相关技术细节. 自定义认证 ...
- Django(72)Django认证系统库--djoser
djoser是什么? 作用:Django认证系统的REST实现.djoser库提供了一组Django Rest Framework视图,用于处理注册.登录.注销.密码重置和帐户激活等基本操作.它适 ...
- Django认证系统auth认证
使用Django认证系统auth认证 auth认证系统可以处理范围非常广泛的任务,且具有一套细致的密码和权限实现.对于需要与默认配置不同需求的项目,Django支持扩展和自定义认证;会将用户信息写入到 ...
- django认证系统 Authentication
Django自带一个用户认证系统,用于处理用户账户.群组.许可和基于cookie的用户会话. Django的认证系统包含了身份验证和权限管理两部分.简单地说,身份验证用于核实某个用户是否合法,权限管理 ...
随机推荐
- python一些实用的小工具
1 搭一个简易的本地局域网 python -m http.server 2 获取当前目录下的所有文件名 3 进度条效果 import sys,time for i in range(50): sy ...
- P3975 (后缀自动机sort)
题目链接: https://www.luogu.org/problem/P3975 题意: 求出所有字串的第k大子串 有两种,第一种对于出现在不同位置的相同子串算作一个子串 第二种,对于不同位置的子串 ...
- [ZJOI2004]嗅探器 (割点)
这题就比较好玩吧水题 以数据范围来看随便怎么做就能过 \(O(n)\)显然我们得过一个割点,其次这个割点得在\(x-y\)中间且不为始终点 其他都好说,在中间:从\(x\)开始遍历,首先得保证\(x- ...
- win10下交换CapLock和Esc按键
win10下使用vim编辑时,需频繁用Esc键,可是Esc键在键盘左上角,位置遥远,操作不便.可以CapsLock键处在黄金位置,但是几乎无用,看过键盘发展历史,其实是是在发展过程中的意外而已,将两键 ...
- C语言应用--数据类型定制一结构体数组
结构体定义成功后,其实和c语言内部的类型区别也不大了,自然可以用来定义结构体类型的数组了.我们根据结构体定义的方式不同,分别用多种方式定义结构体数组:
- ubuntu中编译安装gcc 9.2.0
一切都和其他源码安装软件是一样的: 一.下载源代码: http://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.xz 二.解压文件 tar xvf gcc- ...
- 【原】Python基础-函数
#不定长参数,这里prams是一个元组集合def print_params(*prams): for e in prams: print(e) print(prams) #输出('xxx', (1, ...
- 深入理解JVM虚拟机6:深入理解JVM类加载机制
深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...
- zsh: no matches found
具体原因: 因为zsh缺省情况下始终自己解释这个 *.h,而不会传递给 find 来解释. 解决办法: 在~/.zshrc中加入: setopt no_nomatch, 然后进行source .zsh ...
- RT-Thread 柿饼GUI
目前主流的嵌入式GUI开发技术中,RT-Thread/Persimmon.TouchGFX和emWin是最受人瞩目的. RT-Thread/ Persimmon是国内主导开发的实时线程操作系统RT ...