Django基于Token的驗證使用的實現(xiàn)
什么是Token
Token字面意思是令牌,功能跟Session類似,也是用于驗證用戶信息的,Token是服務端生成的一串字符串,當客戶端發(fā)送登錄請求時,服務器便會生成一個Token并將此Token返回給客戶端,作為客戶端進行請求的一個標識以后客戶端只需帶上這個Token前來請求數(shù)據(jù)即可,無需再次帶上用戶名和密碼。與session的不同之處在于,Session是將用戶信息存儲在服務器中保持用戶的請求狀態(tài),而Token在服務器端不需要存儲用戶的登錄記錄,客戶端每次向服務端發(fā)送請求的時候都會帶上服務端發(fā)給的Token,服務端收到請求后去驗證客戶端請求里面帶著Token,如果驗證成功,就向客戶端返回請求的數(shù)據(jù)。
為什么要用Token
1.Token無需存儲降低服務器成本,session是將用戶信息存儲在服務器中的,當用戶量增大時服務器的壓力也會隨著增大。
2.防御CSRF跨站偽造請求攻擊,session是基于cookie進行用戶識別的, cookie如果被截獲,用戶信息就容易泄露。
3.擴展性強,session需要存儲無法共享,當搭建了多個服務器時其他服務器無法獲取到session中的驗證數(shù)據(jù)用戶無法驗證成功。而Token可以實現(xiàn)服務器間共享,這樣不管哪里都可以訪問到。
4.Token可以減輕服務器的壓力,減少頻繁的查詢數(shù)據(jù)庫。
5.支持跨域訪問
6.適用于移動平臺應用
基于 Token 的身份驗證流程
- 客戶端使用用戶名跟密碼請求登錄
- 服務端收到請求開始驗證用戶名與密碼
- 驗證成功后,服務端生成一個 Token并把這個 Token 發(fā)送給客戶端
- 客戶端收到 Token 以后可以把它存儲起來,可以存放在 Cookie 里或者 Local Storage 里
- 客戶端再次向服務端請求資形式源的時候攜帶服務端生成的 Token發(fā)送給服務器
- 服務端收到請求,然后去驗證客戶端請求里面攜帶的 Token,如果驗證成功,就向客戶端返回請求的數(shù)據(jù),否則拒絕請求。
Token的組成形式
JWT 標準的 Token 有三個部分:
header(頭部)
每個 Token 里面都有一個 header,也就是頭部數(shù)據(jù),里面包含了使用的算法告訴我們這個token 是否加密。如果是未加密的 Token ,這個屬性可以設置成 none。
payload(數(shù)據(jù))
Payload 里面是 Token 要包含的一些數(shù)據(jù),內(nèi)容可以自行定義,也可以參考標準字段(簡寫:全稱)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ā)行時間,過期時間等。
headers={'type':'JWT','alg':'HS256'} payloads={'iss':user,'iat':time.time()}
分別加密headers和payloads,Django中內(nèi)置了一個模塊django.core.signing,可以用它來加密和解密任何數(shù)據(jù),直接調(diào)用dumps和load函數(shù)來實現(xiàn)即可,將headers和payloads加密再用signing.dumps加密再用signing.b64_encode編碼得到一串字符串,然后用MD5加密headers和payloads生成唯一的signature,最后把headers、payloads、signature組合成Token,下面是測試代碼:
接下來把Token帶入到項目中來使用下,為了方便我們把加密封裝成方法直接調(diào)用,這里我分別寫了Encrypt、Decrypt、Token方法來加密解密和封裝Token,最后把token帶到數(shù)據(jù)中返回給前端,這里我用JsonResponse返回數(shù)據(jù),data里面存放用戶請求的數(shù)據(jù),code返回請求的狀態(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')
這時前端請求登錄后可以接受到后臺返回的info數(shù)據(jù),里面包含了data、token和caode,這時我們可以把獲取到的token存起來,一般存放在客戶端的localstorage或者sessionStorage中,下次再次請求時把這個token再發(fā)給服務器,服務器驗證成功后就會返回所需的數(shù)據(jù)了。
到此這篇關于Django基于Token的驗證使用的實現(xiàn)的文章就介紹到這了,更多相關Django Token驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
PyQt5中QSpinBox計數(shù)器的實現(xiàn)
這篇文章主要介紹了PyQt5中QSpinBox計數(shù)器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01Django代碼性能優(yōu)化與Pycharm Profile使用詳解
本文通過一個簡單的實例一步一步引導讀者對其進行全方位的性能優(yōu)化,這篇文章主要給大家介紹了關于Django代碼性能優(yōu)化與Pycharm Profile使用的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2018-08-08Python深度學習之實現(xiàn)卷積神經(jīng)網(wǎng)絡
今天帶大家學習如何使用Python實現(xiàn)卷積神經(jīng)網(wǎng)絡,這是個很難的知識點,文中有非常詳細的介紹,對小伙伴們很有幫助,需要的朋友可以參考下2021-06-06PyTorch中的方法torch.randperm()示例介紹
在 PyTorch 中,torch.randperm(n) 函數(shù)用于生成一個從 0 到 n-1 的隨機排列的整數(shù)序列,這篇文章主要介紹了PyTorch中的方法torch.randperm()介紹,需要的朋友可以參考下2024-05-05