非常詳細的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.pswp.cn/news/391928.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391928.shtml
英文地址,請注明出處:http://en.pswp.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: , ,摘 要 高校校園網數據…