非常详细的Django使用Token(转)

基于Token的身份验证

在实现登录功能的时候,正常的B/S应用都会使用cookie+session的方式来做身份验证,后台直接向cookie中写数据,但是由于移动端的存在,移动端是没有cookie机制的,所以使用token可以实现移动端和客户端的token通信。

验证流程

整个基于Token的验证流程如下:

  1. 客户端使用用户名跟密码请求登录
  2. 服务器收到请求,去验证用户名和密码
  3. 验证成功后,服务端会签发一个Token,再把这个Token发送到客户端
  4. 客户端收到的Token以后可以把它存储起来,比如放在Cookie或LocalStorage里
  5. 客户端每次向服务器发送其他请求的时候都要带着服务器签发的Token
  6. 服务器收到请求,去验证客户端请求里面带着的Token,如果验证成功,就像客户端返回请求的数据

1493082-20190802091058069-94249073.png

JWT

构造Token的方法挺多的,可以说只要是客户端和服务器端约定好了格式,是想怎么写就怎么写的,然而还有一些标准写法,例如JWT读作/jot/,表示:JSON Web Tokens.
JWT标准的Token有三个部分:

  • header
  • payload
  • signature
    三个部分会用点分割开,并且都会使用Base64编码,所以真正的Token看起来像这样
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

Header

header部分主要是两部分内容,一个是Token的类型,另一个是使用的算法,比如下面的类型就是JWT,使用的算法是HS256:

{"typ": "JWT","alg": "HS256"
}

上面的内容要用 Base64 的形式编码一下,所以就变成这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:

  • iss:Issuer,发行者
  • sub:Subject,主题
  • aud:Audience,观众
  • exp:Expiration time,过期时间
  • nbf:Not before
  • iat:Issued at,发行时间
  • jti:JWT ID

Signature

JWT的最后一部分是Signature,这部分相当于前两段的摘要,用来防止其他人来篡改Token中的信息,在处理时可以首先将前两段生成的内容使用Base64生成一下再加盐然后利用MD5等摘要算法在生成一遍

服务端生成Token

在服务端生成Token的时候,需要解决两个问题

  1. 使用什么加密算法
  2. Token如何存储

加密算法

这里的加密算法并不是MD5,SHA1这样的哈希算法,因为这种算法是无法解密的,只能用来生成摘要,在Django中内置了一个加密前面模块django.core.signing模块,可以用来加密和解密任何数据,使用签名模块的dumps和load函数来实现

示例:

from django.core import signing
value = signing.dumps({"foo":"bar"})
src = signing.loads(value)
print(value)
print(src)

结果:

eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI 
{‘foo’: ‘bar’}

Token如何存储

用什么存储

在服务器中Token可以存储在内存中,因为本质是字符串,所以并不会占用很大的内存空间,如果是分布式的存储可以将所有的token信息分段存储在不同的服务器中,也可以存储在数据库中,在Django中提供了缓存类,可以用来存储Token,Django的缓存可以结合Redis来使用,可以借助django-redis来实现

安装

pip install django-redis

配置

为了使用django-redis,需要将django cache setting修改,修改settings.py,默认是没有Cache的配置信息的,在其中添加:

CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}}
}

当然,需要你首先安装了redis

cache使用

cache使用的时候基本可以使用set和get方法来进行存/取数据

>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'

如何存

由于redis是使用k-v模式来进行存储数据的,我们可以使用用户名作为key,而token信息作为value,相较于直接使用token作为key的方式,好处是我们可以使用更少的空间实现一些功能,例如当用户修改了密码或点击注销之后,它的token可以直接失效,直接将该用户名所对应的数据删除就好了,或者用户在一次登录成功后,又一次请求了登录接口,我们可以很简单的更新该用户的token信息,而这样存储所依赖于我们的token可以进行解密,如果你是直接生成了一串无法解密的数据作为token,不能使用用户名作为token了

code

import time
from django.core import signing
import hashlib
from django.core.cache import cacheHEADER = {'typ': 'JWP', 'alg': 'default'}
KEY = 'CHEN_FENG_YAO'
SALT = 'www.lanou3g.com'
TIME_OUT = 30 * 60  # 30mindef encrypt(obj):"""加密"""value = signing.dumps(obj, key=KEY, salt=SALT)value = signing.b64_encode(value.encode()).decode()return valuedef decrypt(src):"""解密"""src = signing.b64_decode(src.encode()).decode()raw = signing.loads(src, key=KEY, salt=SALT)print(type(raw))return rawdef create_token(username):"""生成token信息"""# 1. 加密头信息header = encrypt(HEADER)# 2. 构造Payloadpayload = {"username": username, "iat": time.time()}payload = encrypt(payload)# 3. 生成签名md5 = hashlib.md5()md5.update(("%s.%s" % (header, payload)).encode())signature = md5.hexdigest()token = "%s.%s.%s" % (header, payload, signature)# 存储到缓存中cache.set(username, token, TIME_OUT)return tokendef get_payload(token):payload = str(token).split('.')[1]payload = decrypt(payload)return payload# 通过token获取用户名
def get_username(token):payload = get_payload(token)return payload['username']passdef check_token(token):username = get_username(token)last_token = cache.get(username)if last_token:return last_token == tokenreturn False

转载于:https://www.cnblogs.com/Paul-watermelon/p/11286698.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中获取完整的url

HttpServletRequest httpRequest(HttpServletRequest)request; String strBackUrl "http://" request.getServerName() //服务器地址 ":" request.getServerPort() //端口号 httpRequest.getContextPath() //项目名称 httpRequ…

数据科学中的数据可视化

数据可视化简介 (Introduction to Data Visualization) Data visualization is the process of creating interactive visuals to understand trends, variations, and derive meaningful insights from the data. Data visualization is used mainly for data checking and cl…

打针小说软件测试,UPDATE注射(mysql+php)的两个模式

一.---- 表的结构 userinfo--CREATE TABLE userinfo (groudid varchar(12) NOT NULL default 1,user varchar(12) NOT NULL default heige,pass varchar(122) NOT NULL default 123456) ENGINEMyISAM DEFAULT CHARSETlatin1;---- 导出表中的数据 userinfo--INSERT INTO userinf…

前端速成班_在此速成班中学习Go

前端速成班Learn everything you need to get started programming in Go with this crash course tutorial.通过该速成课程教程,学习在Go中开始编程所需的一切。 First, learn how to install a Go Programming Environment on Windows, Mac, or Linux. Then, lea…

手把手教你webpack3(6)css-loader详细使用说明

CSS-LOADER配置详解 前注: 文档全文请查看 根目录的文档说明。 如果可以,请给本项目加【Star】和【Fork】持续关注。 有疑义请点击这里,发【Issues】。 1、概述 对于一般的css文件,我们需要动用三个loader(是不是觉得好…

shell远程执行命令

1、先要配置免密登陆&#xff0c;查看上一篇免密传输内容 2、命令行执行少量命令&#xff1a;ssh ip "command1;command2"。例&#xff1a;ssh 172.1.1.1 "cd /home;ls" 3、脚本批量执行命令&#xff1a; #&#xff01;/bin/bash ssh ip << remotes…

Python调用C语言

Python中的ctypes模块可能是Python调用C方法中最简单的一种。ctypes模块提供了和C语言兼容的数据类型和函数来加载dll文件&#xff0c;因此在调用时不需对源文件做任何的修改。也正是如此奠定了这种方法的简单性。 示例如下 实现两数求和的C代码&#xff0c;保存为add.c //samp…

多重线性回归 多元线性回归_了解多元线性回归

多重线性回归 多元线性回归Video Link影片连结 We have taken a look at Simple Linear Regression in Episode 4.1 where we had one variable x to predict y, but what if now we have multiple variables, not just x, but x1,x2, x3 … to predict y — how would we app…

tp703n怎么做无线打印服务器,TP-Link TL-WR703N无线路由器无线AP模式怎么设置

TP-Link TL-WR703N无线路由器配置简单&#xff0c;不过对于没有网络基础的用户来说&#xff0c;完成路由器的安装和无线AP模式的设置&#xff0c;仍然有一定的困难&#xff0c;本文学习啦小编主要介绍TP-Link TL-WR703N无线路由器无线AP模式的设置方法!TP-Link TL-WR703N无线路…

unity 克隆_使用Unity开发Portal游戏克隆

unity 克隆Learn game development principles by coding a Portal-like game using Unity and C#. The principles you learn in this lecture from Colton Ogden can apply to any programming language and any game.通过使用Unity和C&#xff03;编写类似于Portal的游戏来学…

swift基础学习(八)

####1.主要用到的知识点 CAGradientLayer 处理渐变色AVAudioPlayer 音频播放Timer 定时器CABasicAnimation 动画#####2.效果图 ####3.代码 import UIKit import AVFoundationclass ViewController: UIViewController, AVAudioPlayerDelegate {var gradientLayer: CAGradientLay…

pandas之groupby分组与pivot_table透视

一、groupby 类似excel的数据透视表&#xff0c;一般是按照行进行分组&#xff0c;使用方法如下。 df.groupby(byNone, axis0, levelNone, as_indexTrue, sortTrue, group_keysTrue,squeezeFalse, observedFalse, **kwargs) 分组得到的直接结果是一个DataFrameGroupBy对象。 df…

js能否打印服务器端文档,js打印远程服务器文件

js打印远程服务器文件 内容精选换一换对于密码鉴权方式创建的Windows 2012弹性云服务器&#xff0c;使用初始密码以MSTSC方式登录时&#xff0c;登录失败&#xff0c;系统显示“第一次登录之前&#xff0c;你必须更改密码。请更新密码&#xff0c;或者与系统管理员或技术支持联…

spring—JdbcTemplate使用

JdbcTemplate基本使用 01-JdbcTemplate基本使用-概述(了解) JdbcTemplate是spring框架中提供的一个对象&#xff0c;是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如&#xff1a;操作关系型数据的JdbcTemplate和HibernateTemplate&…

vanilla_如何在Vanilla JavaScript中操作DOM

vanillaby carlos da costa通过卡洛斯达科斯塔 如何在Vanilla JavaScript中操作DOM (How to manipulate the DOM in Vanilla JavaScript) So you have learned variables, selection structures, and loops. Now it is time to learn about DOM manipulation and to start doi…

NOIP201202寻宝

题目 试题描述传说很遥远的藏宝楼顶层藏着诱人的宝藏。 小明历尽千辛万苦终于找到传说中的这个藏宝楼&#xff0c;藏宝楼的门口竖着一个木板&#xff0c;上面写有几个大字&#xff1a;寻宝说明书。说明书的内容如下&#xff1a;藏宝楼共有N1层&#xff0c;最上面一层是顶层&…

修改UITextField中的placeholder的字体

修改字体颜色&#xff1a; [textField setValue:[UIColor redColor] forKeyPath:"_placeholderLabel.textColor"]; 复制代码 修改字体大小&#xff1a; [textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:"_placeholderLabel.font"]; 复…

如何使用Python处理丢失的数据

The complete notebook and required datasets can be found in the git repo here完整的笔记本和所需的数据集可以在git repo中找到 Real-world data often has missing values.实际数据通常缺少值 。 Data can have missing values for a number of reasons such as observ…

MySQL—隔离级别

READ UNCOMMITED(读未提交) 即读取到了正在修改但是却还没有提交的数据&#xff0c;这就会造成数据读取的错误。 READ COMMITED(提交读/不可重复读) 它与READ UNCOMMITED的区别在于&#xff0c;它规定读取的时候读到的数据只能是提交后的数据。 这个级别所带来的问题就是不可…

做虚拟化服务器的配资一致嘛,服务器虚拟化技术在校园网管理中的应用探讨.pdf...

第 卷 第 期 江 苏 建 筑 职 业 技 术 学 院 学 报14 3 Vol.14 曧.3年 月 JOURNAL OF JIANGSU JIANZHU INSTITUTE2014 09 Se .2014p服务器虚拟化技术在校园网管理中的应用探讨,汪小霞 江建( , )健雄职业技术学院 软件与服务外包学院 江苏 太仓 215411: , ,摘 要 高校校园网数据…