电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

python中JWT用戶認證的實現

瀏覽:54日期:2022-07-25 10:06:26

在前后端分離開發時為什么需要用戶認證呢?原因是由于HTTP協定是不儲存狀態的(stateless),這意味著當我們透過帳號密碼驗證一個使用者時,當下一個request請求時它就把剛剛的資料忘了。于是我們的程序就不知道誰是誰,就要再驗證一次。所以為了保證系統安全,我們就需要驗證用戶否處于登錄狀態。

一、傳統方式

前后端分離通過Restful API進行數據交互時,如何驗證用戶的登錄信息及權限。在原來的項目中,使用的是最傳統也是最簡單的方式,前端登錄,后端根據用戶信息生成一個token,并保存這個token 和對應的用戶id到數據庫或Session中,接著把token 傳給用戶,存入瀏覽器 cookie,之后瀏覽器請求帶上這個cookie,后端根據這個cookie值來查詢用戶,驗證是否過期。

但這樣做問題就很多,如果我們的頁面出現了 XSS 漏洞,由于 cookie 可以被 JavaScript 讀取,XSS 漏洞會導致用戶 token 泄露,而作為后端識別用戶的標識,cookie 的泄露意味著用戶信息不再安全。盡管我們通過轉義輸出內容,使用 CDN 等可以盡量避免 XSS 注入,但誰也不能保證在大型的項目中不會出現這個問題。

在設置 cookie 的時候,其實你還可以設置 httpOnly 以及 secure項。設置 httpOnly后 cookie 將不能被 JS 讀取,瀏覽器會自動的把它加在請求的 header 當中,設置 secure的話,cookie 就只允許通過 HTTPS 傳輸。secure 選項可以過濾掉一些使用 HTTP 協議的 XSS 注入,但并不能完全阻止。

httpOnly 選項使得 JS 不能讀取到 cookie,那么 XSS 注入的問題也基本不用擔心了。但設置 httpOnly就帶來了另一個問題,就是很容易的被 XSRF,即跨站請求偽造。當你瀏覽器開著這個頁面的時候,另一個頁面可以很容易的跨站請求這個頁面的內容。因為 cookie 默認被發了出去。

另外,如果將驗證信息保存在數據庫中,后端每次都需要根據token查出用戶id,這就增加了數據庫的查詢和存儲開銷。若把驗證信息保存在session中,有加大了服務器端的存儲壓力。那我們可不可以不要服務器去查詢呢?如果我們生成token遵循一定的規律,比如我們使用對稱加密算法來加密用戶id形成token,那么服務端以后其實只要解密該token就可以知道用戶的id是什么了。不過呢,我只是舉個例子而已,要是真這么做,只要你的對稱加密算法泄露了,其他人可以通過這種加密方式進行偽造token,那么所有用戶信息都不再安全了。恩,那用非對稱加密算法來做呢,其實現在有個規范就是這樣做的,就是我們接下來要介紹的 JWT。

二、Json Web Token(JWT)

WT 是一個開放標準(RFC 7519),它定義了一種用于簡潔,自包含的用于通信雙方之間以 JSON 對象的形式安全傳遞信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公鑰密鑰對進行簽名。它具備兩個特點:

簡潔(Compact)

可以通過URL, POST 參數或者在 HTTP header 發送,因為數據量小,傳輸速度快

自包含(Self-contained)

負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫

JWT 組成

Header 頭部

頭部包含了兩部分,token 類型和采用的加密算法

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

它會使用 Base64 編碼組成 JWT 結構的第一部分,如果你使用Node.js,可以用Node.js的包base64url來得到這個字符串。------------ Base64是一種編碼,也就是說,它是可以被翻譯回原來的樣子來的。它并不是一種加密過程。

Payload 負載

負載就是存放有效信息的地方。這些有效信息包含三個部分:----標準中注冊聲明----公共的聲明----私有的聲明

公共的聲明:

公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密。

私有的聲明:

私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息

{ 'iss': 'lion1ou JWT', 'iat': 1441593502, 'exp': 1441594722, 'aud': 'www.example.com', 'sub': 'lion1ou@163.com'}// 包括需要傳遞的用戶信息;{ 'iss': 'Online JWT Builder', 'iat': 1416797419, 'exp': 1448333419, 'aud': 'www.gusibi.com', 'sub': 'uid', 'nickname': 'goodspeed', 'username': 'goodspeed', 'scopes': [ 'admin', 'user' ] } iss: 該JWT的簽發者,是否使用是可選的; sub: 該JWT所面向的用戶,是否使用是可選的; aud: 接收該JWT的一方,是否使用是可選的; exp(expires): 什么時候過期,這里是一個Unix時間戳,是否使用是可選的; iat(issued at): 在什么時候簽發的(UNIX時間),是否使用是可選的;

其他還有:

nbf (Not Before):如果當前時間在nbf里的時間之前,則Token不被接受;一般都會留一些余地,比如幾分鐘;,是否使用是可選的; jti: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。 同樣的,它會使用 Base64 編碼組成 JWT 結構的第二部分。 Signature 簽名

前面兩部分都是使用 Base64 進行編碼的,即前端可以解開知道里面的信息。Signature 需要使用編碼后的 header 和 payload 以及我們提供的一個密鑰,然后使用 header 中指定的簽名算法(HS256)進行簽名。簽名的作用是保證 JWT 沒有被篡改過。

// 根據alg算法與私有秘鑰進行加密得到的簽名字串;// 這一段是最重要的敏感信息,只能在服務端解密;HMACSHA256( base64UrlEncode(header) + '.' + base64UrlEncode(payload), SECREATE_KEY)

三個部分通過.連接在一起就是我們的 JWT 了,它可能長這個樣子,長度貌似和你的加密算法和私鑰有關系。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU3ZmVmMTY0ZTU0YWY2NGZmYzUzZGJkNSIsInhzcmYiOiI0ZWE1YzUwOGE2NTY2ZTc2MjQwNTQzZjhmZWIwNmZkNDU3Nzc3YmUzOTU0OWM0MDE2NDM2YWZkYTY1ZDIzMzBlIiwiaWF0IjoxNDc2NDI3OTMzfQ.PA3QjeyZSUh7H0GfE0vJaKW4LjKJuC3dVLQiY4hii8s

其實到這一步可能就有人會想了,HTTP 請求總會帶上 token,這樣這個 token 傳來傳去占用不必要的帶寬啊。如果你這么想了,那你可以去了解下 HTTP2,HTTP2 對頭部進行了壓縮,相信也解決了這個問題。

簽名的目的

最后一步簽名的過程,實際上是對頭部以及負載內容進行簽名,防止內容被竄改。如果有人對頭部以及負載的內容解碼之后進行修改,再進行編碼,最后加上之前的簽名組合形成新的JWT的話,那么服務器端會判斷出新的頭部和負載形成的簽名和JWT附帶上的簽名是不一樣的。如果要對新的頭部和負載進行簽名,在不知道服務器加密時用的密鑰的話,得出來的簽名也是不一樣的。

信息暴露

在這里大家一定會問一個問題:Base64是一種編碼,是可逆的,那么我的信息不就被暴露了嗎?

是的。所以,在JWT中,不應該在負載里面加入任何敏感的數據。在上面的例子中,我們傳輸的是用戶的User ID。這個值實際上不是什么敏感內容,一般情況下被知道也是安全的。但是像密碼這樣的內容就不能被放在JWT中了。如果將用戶的密碼放在了JWT中,那么懷有惡意的第三方通過Base64解碼就能很快地知道你的密碼了。

因此JWT適合用于向Web應用傳遞一些非敏感信息。JWT還經常用于設計用戶認證和授權系統,甚至實現Web應用的單點登錄。

token 生成好之后,接下來就可以用token來和服務器進行通訊了。

三、JWT 使用

下圖是client 使用 JWT 與server 交互過程:

python中JWT用戶認證的實現

1.這里在第三步我們得到 JWT 之后,需要將JWT存放在 client,之后的每次需要認證的請求都要把JWT發送過來。(請求時可以放到 header 的 Authorization )首先,前端通過Web表單將自己的用戶名和密碼發送到后端的接口。這一過程一般是一個HTTP POST請求。建議的方式是通過SSL加密的傳輸(https協議),從而避免敏感信息被嗅探。

2.后端核對用戶名和密碼成功后,將用戶的id等其他信息作為JWT Payload(負載),將其與頭部分別進行Base64編碼拼接后簽名,形成一個JWT。形成的JWT就是一個形同lll.zzz.xxx的字符串。

3.后端將JWT字符串作為登錄成功的返回結果返回給前端。前端可以將返回的結果保存在localStorage或sessionStorage上,退出登錄時前端刪除保存的JWT即可。

4.前端在每次請求時將JWT放入HTTP Header中的Authorization位。(解決XSS和XSRF問題)

5.后端檢查是否存在,如存在驗證JWT的有效性。例如,檢查簽名是否正確;檢查Token是否過期;檢查Token的接收方是否是自己(可選)。

6.驗證通過后后端使用JWT中包含的用戶信息進行其他邏輯操作,返回相應結果。

四、JWT 使用場景

WT的主要優勢在于使用無狀態、可擴展的方式處理應用中的用戶會話。服務端可以通過內嵌的聲明信息,很容易地獲取用戶的會話信息,而不需要去訪問用戶或會話的數據庫。在一個分布式的面向服務的框架中,這一點非常有用。

但是,如果系統中需要使用黑名單實現長期有效的token刷新機制,這種無狀態的優勢就不明顯了。

優點快速開發不需要cookieJSON在移動端的廣泛應用不依賴于社交登錄相對簡單的概念理解

缺點Token有長度限制Token不能撤銷需要token有失效時間限制(exp)

五、和Session方式存儲id的差異

Session方式存儲用戶id的最大弊病在于Session是存儲在服務器端的,所以需要占用大量服務器內存,對于較大型應用而言可能還要保存許多的狀態。一般而言,大型應用還需要借助一些KV數據庫和一系列緩存機制來實現Session的存儲。

而JWT方式將用戶狀態分散到了客戶端中,可以明顯減輕服務端的內存壓力。除了用戶id之外,還可以存儲其他的和用戶相關的信息,例如該用戶是否是管理員、用戶所在的分組等。雖說JWT方式讓服務器有一些計算壓力(例如加密、編碼和解碼),但是這些壓力相比磁盤存儲而言可能就不算什么了。具體是否采用,需要在不同場景下用數據說話。

單點登錄

Session方式來存儲用戶id,一開始用戶的Session只會存儲在一臺服務器上。對于有多個子域名的站點,每個子域名至少會對應一臺不同的服務器,例如:www.taobao.com,nv.taobao.com,nz.taobao.com,login.taobao.com。所以如果要實現在login.taobao.com登錄后,在其他的子域名下依然可以取到Session,這要求我們在多臺服務器上同步Session。使用JWT的方式則沒有這個問題的存在,因為用戶的狀態已經被傳送到了客戶端。

六、總結

JWT的主要作用在于:(一)可附帶用戶信息,后端直接通過JWT獲取相關信息。(二)使用本地保存,通過HTTP Header中的Authorization位提交驗證。

七、附加,python使用JWT

python 中djagno rest framework要使用jwt,可以使用以下這個模塊:githubs文檔有使用說明https://github.com/GetBlimp/django-rest-framework-jwt

pip install djangorestframework-jwt

不是使用django的話,我們可以使用 pyjwt:https://github.com/jpadilla/pyjwt/使用比較方便,下邊是我在應用中使用的例子:

import jwtimport time# 使用 sanic 作為restful api 框架 def create_token(request): grant_type = request.json.get(’grant_type’) username = request.json[’username’] password = request.json[’password’] if grant_type == ’password’: account = verify_password(username, password) elif grant_type == ’wxapp’: account = verify_wxapp(username, password) if not account: return {} payload = { 'iss': 'gusibi.com', 'iat': int(time.time()), 'exp': int(time.time()) + 86400 * 7, 'aud': 'www.gusibi.com', 'sub': account[’_id’], 'username': account[’username’], 'scopes': [’open’] } token = jwt.encode(payload, ’secret’, algorithm=’HS256’) return True, {’access_token’: token, ’account_id’: account[’_id’]} def verify_bearer_token(token): # 如果在生成token的時候使用了aud參數,那么校驗的時候也需要添加此參數 payload = jwt.decode(token, ’secret’, audience=’www.gusibi.com’, algorithms=[’HS256’]) if payload: return True, token return False, token

到此這篇關于python中JWT用戶認證的實現的文章就介紹到這了,更多相關python JWT用戶認證內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 隐形纱窗|防护纱窗|金刚网防盗纱窗|韦柏纱窗|上海青木装潢制品有限公司|纱窗国标起草单位 | 整合营销推广|营销网络推广公司|石家庄网站优化推广公司|智营销 好物生环保网、环保论坛 - 环保人的学习交流平台 | 移动机器人产业联盟官网 | 圆周直径尺-小孔内视镜-纤维研磨刷-东莞市高腾达精密工具 | LNG鹤管_内浮盘价格,上装鹤管,装车撬厂家-连云港赛威特机械 | 生产加气砖设备厂家很多,杜甫机械加气砖设备价格公道 | 上海盐水喷雾试验机_两厢式冷热冲击试验箱-巨怡环试 | 代办建筑资质升级-建筑资质延期就找上海国信启航 | 盛源真空泵|空压机-浙江盛源空压机制造有限公司-【盛源官网】 | 深圳办公室装修,办公楼/写字楼装修设计,一级资质 - ADD写艺 | 拖鞋定制厂家-品牌拖鞋代加工厂-振扬实业中国高端拖鞋大型制造商 | 钢木实验台-全钢实验台-化验室通风柜-实验室装修厂家-杭州博扬实验设备 | 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 超声骨密度仪,双能X射线骨密度仪【起草单位】,骨密度检测仪厂家 - 品源医疗(江苏)有限公司 | 云阳人才网_云阳招聘网_云阳人才市场_云阳人事人才网_云阳人家招聘网_云阳最新招聘信息 | 购买舔盐、舔砖、矿物质盐压块机,鱼饵、鱼饲料压块机--请到杜甫机械 | 凝胶成像仪,化学发光凝胶成像系统,凝胶成像分析系统-上海培清科技有限公司 | 上海瑶恒实业有限公司|消防泵泵|离心泵|官网 | 上海风淋室_上海风淋室厂家_上海风淋室价格_上海伯淋 | 动力配电箱-不锈钢配电箱-高压开关柜-重庆宇轩机电设备有限公司 聚天冬氨酸,亚氨基二琥珀酸四钠,PASP,IDS - 远联化工 | 品牌设计_VI设计_电影海报设计_包装设计_LOGO设计-Bacross新越品牌顾问 | 无线对讲-无线对讲系统解决方案-重庆畅博通信 | 【同风运车官网】一站式汽车托运服务平台,验车满意再付款 | 洗地机_全自动洗地机_手推式洗地机【上海滢皓环保】 | 标准件-非标紧固件-不锈钢螺栓-非标不锈钢螺丝-非标螺母厂家-三角牙锁紧自攻-南京宝宇标准件有限公司 | 冷藏车-东风吸污车-纯电动环卫车-污水净化车-应急特勤保障车-程力专汽厂家-程力专用汽车股份有限公司销售二十一分公司 | 污水提升器,污水提升泵,地下室排水,增压泵,雨水泵,智能供排水控制器-上海智流泵业有限公司 | 济南ISO9000认证咨询代理公司,ISO9001认证,CMA实验室认证,ISO/TS16949认证,服务体系认证,资产管理体系认证,SC食品生产许可证- 济南创远企业管理咨询有限公司 郑州电线电缆厂家-防火|低压|低烟无卤电缆-河南明星电缆 | 环氧树脂地坪漆_济宁市新天地漆业有限公司| 武汉宣传片制作-视频拍摄-企业宣传片公司-武汉红年影视 | 紫外可见光分光度计-紫外分光度计-分光光度仪-屹谱仪器制造(上海)有限公司 | 酒瓶_酒杯_玻璃瓶生产厂家_徐州明政玻璃制品有限公司 | 水篦子|雨篦子|镀锌格栅雨水篦子|不锈钢排水篦子|地下车库水箅子—安平县云航丝网制品厂 | 合肥角钢_合肥槽钢_安徽镀锌管厂家-昆瑟商贸有限公司 | 工业CT-无锡璟能智能仪器有限公司| 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 带锯机|木工带锯机圆木推台锯|跑车带锯机|河北茂业机械制造有限公司| | 机构创新组合设计实验台_液压实验台_气动实训台-戴育教仪厂 | 塑钢件_塑钢门窗配件_塑钢配件厂家-文安县启泰金属制品有限公司 深圳南财多媒体有限公司介绍 | 便携式表面粗糙度仪-彩屏硬度计-分体式粗糙度仪-北京凯达科仪科技有限公司 | 曙光腾达官网-天津脚手架租赁-木板架出租-移动门式脚手架租赁「免费搭设」 |