Django基于Token的驗(yàn)證使用的實(shí)現(xiàn)
什么是Token
Token字面意思是令牌,功能跟Session類似,也是用于驗(yàn)證用戶信息的,Token是服務(wù)端生成的一串字符串,當(dāng)客戶端發(fā)送登錄請(qǐng)求時(shí),服務(wù)器便會(huì)生成一個(gè)Token并將此Token返回給客戶端,作為客戶端進(jìn)行請(qǐng)求的一個(gè)標(biāo)識(shí)以后客戶端只需帶上這個(gè)Token前來請(qǐng)求數(shù)據(jù)即可,無需再次帶上用戶名和密碼。與session的不同之處在于,Session是將用戶信息存儲(chǔ)在服務(wù)器中保持用戶的請(qǐng)求狀態(tài),而Token在服務(wù)器端不需要存儲(chǔ)用戶的登錄記錄,客戶端每次向服務(wù)端發(fā)送請(qǐng)求的時(shí)候都會(huì)帶上服務(wù)端發(fā)給的Token,服務(wù)端收到請(qǐng)求后去驗(yàn)證客戶端請(qǐng)求里面帶著Token,如果驗(yàn)證成功,就向客戶端返回請(qǐng)求的數(shù)據(jù)。

為什么要用Token
1.Token無需存儲(chǔ)降低服務(wù)器成本,session是將用戶信息存儲(chǔ)在服務(wù)器中的,當(dāng)用戶量增大時(shí)服務(wù)器的壓力也會(huì)隨著增大。
2.防御CSRF跨站偽造請(qǐng)求攻擊,session是基于cookie進(jìn)行用戶識(shí)別的, cookie如果被截獲,用戶信息就容易泄露。
3.擴(kuò)展性強(qiáng),session需要存儲(chǔ)無法共享,當(dāng)搭建了多個(gè)服務(wù)器時(shí)其他服務(wù)器無法獲取到session中的驗(yàn)證數(shù)據(jù)用戶無法驗(yàn)證成功。而Token可以實(shí)現(xiàn)服務(wù)器間共享,這樣不管哪里都可以訪問到。
4.Token可以減輕服務(wù)器的壓力,減少頻繁的查詢數(shù)據(jù)庫(kù)。
5.支持跨域訪問
6.適用于移動(dòng)平臺(tái)應(yīng)用

基于 Token 的身份驗(yàn)證流程
- 客戶端使用用戶名跟密碼請(qǐng)求登錄
- 服務(wù)端收到請(qǐng)求開始驗(yàn)證用戶名與密碼
- 驗(yàn)證成功后,服務(wù)端生成一個(gè) Token并把這個(gè) Token 發(fā)送給客戶端
- 客戶端收到 Token 以后可以把它存儲(chǔ)起來,可以存放在 Cookie 里或者 Local Storage 里
- 客戶端再次向服務(wù)端請(qǐng)求資形式源的時(shí)候攜帶服務(wù)端生成的 Token發(fā)送給服務(wù)器
- 服務(wù)端收到請(qǐng)求,然后去驗(yàn)證客戶端請(qǐng)求里面攜帶的 Token,如果驗(yàn)證成功,就向客戶端返回請(qǐng)求的數(shù)據(jù),否則拒絕請(qǐng)求。

Token的組成形式
JWT 標(biāo)準(zhǔn)的 Token 有三個(gè)部分:
header(頭部)
每個(gè) Token 里面都有一個(gè) header,也就是頭部數(shù)據(jù),里面包含了使用的算法告訴我們這個(gè)token 是否加密。如果是未加密的 Token ,這個(gè)屬性可以設(shè)置成 none。
payload(數(shù)據(jù))
Payload 里面是 Token 要包含的一些數(shù)據(jù),內(nèi)容可以自行定義,也可以參考標(biāo)準(zhǔn)字段(簡(jiǎn)寫:全稱)iss:Issuer、sub:Subject、exp:Expiration time、iat:Issued at。
signature(簽名)
將Header和Playload使用Base64編碼生成一下再加入簽名字符用加密算法加密一遍,得到唯一的簽名,用來防止其他人來篡改Token中的信息。

Django如何使用Token
即然我們知道Token的組成方式,那么我們就來創(chuàng)建下Token,首定義Header和Payload,header中定義token類型和加密方式,Payload定義具體內(nèi)容,如何用戶名,發(fā)行時(shí)間,過期時(shí)間等。
headers={'type':'JWT','alg':'HS256'}
payloads={'iss':user,'iat':time.time()}
分別加密headers和payloads,Django中內(nèi)置了一個(gè)模塊django.core.signing,可以用它來加密和解密任何數(shù)據(jù),直接調(diào)用dumps和load函數(shù)來實(shí)現(xiàn)即可,將headers和payloads加密再用signing.dumps加密再用signing.b64_encode編碼得到一串字符串,然后用MD5加密headers和payloads生成唯一的signature,最后把headers、payloads、signature組合成Token,下面是測(cè)試代碼:

接下來把Token帶入到項(xiàng)目中來使用下,為了方便我們把加密封裝成方法直接調(diào)用,這里我分別寫了Encrypt、Decrypt、Token方法來加密解密和封裝Token,最后把token帶到數(shù)據(jù)中返回給前端,這里我用JsonResponse返回?cái)?shù)據(jù),data里面存放用戶請(qǐng)求的數(shù)據(jù),code返回請(qǐng)求的狀態(tài),token里面存放我們的token令牌。
HEADER={
'type':'JWT',
'alg':'HS256'
}
def Encrypt(value):
data=signing.dumps(value)
data=signing.b64_encode(data.encode()).decode()
return data
def Decrypt(value):
data=signing.b64_decode(value.encode()).decode()
data=signing.loads(data)
return data
def Token(headers,payloads):
header=Encrypt(headers)
payload=Encrypt(payloads)
md5=hashlib.md5()
md5.update(("%s.%s"%(header,payload)).encode())
signature=md5.hexdigest()
token="%s.%s.%s"%(header,payload,signature)
return token
def login(request):
user = request.POST.get('username').strip()
pwd = request.POST.get('password').strip()
print(request.method)
# print(user,pwd)
obj=models.Admin.objects.filter(name=user)
if obj:
print('456789')
passwd=models.Admin.objects.filter(name=user).values('password')[0]['password']
ret=check_password(pwd,passwd)
userobj=models.Admin.objects.get(name=user)
print('ret=',ret)
if ret:
headers=HEADER
data={'phone': userobj.phone, 'mail': userobj.mail}
payloads={'iss': userobj.name, 'iat':time.time()}
token=Token(headers,payloads)
print(token)
info={'token':token}
info['code']=200
info['data']=data
print(info)
return JsonResponse(info)
else:
return HttpResponse('400')
else:
return HttpResponse('400')
這時(shí)前端請(qǐng)求登錄后可以接受到后臺(tái)返回的info數(shù)據(jù),里面包含了data、token和caode,這時(shí)我們可以把獲取到的token存起來,一般存放在客戶端的localstorage或者sessionStorage中,下次再次請(qǐng)求時(shí)把這個(gè)token再發(fā)給服務(wù)器,服務(wù)器驗(yàn)證成功后就會(huì)返回所需的數(shù)據(jù)了。

到此這篇關(guān)于Django基于Token的驗(yàn)證使用的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Django Token驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)模擬錕斤拷等各類亂碼詳解
說到亂碼問題就不得不提到錕斤拷,這算是非常常見的一種亂碼形式,那么它到底是經(jīng)過何種錯(cuò)誤操作產(chǎn)生的呢?本文我們就來一步步探究2023-02-02
PyQt5中QSpinBox計(jì)數(shù)器的實(shí)現(xiàn)
這篇文章主要介紹了PyQt5中QSpinBox計(jì)數(shù)器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Django代碼性能優(yōu)化與Pycharm Profile使用詳解
本文通過一個(gè)簡(jiǎn)單的實(shí)例一步一步引導(dǎo)讀者對(duì)其進(jìn)行全方位的性能優(yōu)化,這篇文章主要給大家介紹了關(guān)于Django代碼性能優(yōu)化與Pycharm Profile使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-08-08
Python深度學(xué)習(xí)之實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)
今天帶大家學(xué)習(xí)如何使用Python實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò),這是個(gè)很難的知識(shí)點(diǎn),文中有非常詳細(xì)的介紹,對(duì)小伙伴們很有幫助,需要的朋友可以參考下2021-06-06
PyTorch中的方法torch.randperm()示例介紹
在 PyTorch 中,torch.randperm(n) 函數(shù)用于生成一個(gè)從 0 到 n-1 的隨機(jī)排列的整數(shù)序列,這篇文章主要介紹了PyTorch中的方法torch.randperm()介紹,需要的朋友可以參考下2024-05-05
django寫用戶登錄判定并跳轉(zhuǎn)制定頁(yè)面的實(shí)例
今天小編就為大家分享一篇django寫用戶登錄判定并跳轉(zhuǎn)制定頁(yè)面的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08

