還分不清 Cookie趣斤、Session、Token黎休、JWT浓领?

來自:掘金(作者:秋天不落葉)
原文鏈接
https://juejin.im/post/6844904034181070861


什么是認(rèn)證(Authentication)

  • 通俗地講就是驗(yàn)證當(dāng)前用戶的身份,證明“你是你自己”(比如:你每天上下班打卡势腮,都需要通過指紋打卡联贩,當(dāng)你的指紋和系統(tǒng)里錄入的指紋相匹配時,就打卡成功)

  • 互聯(lián)網(wǎng)中的認(rèn)證:

  • 用戶名密碼登錄

  • 郵箱發(fā)送登錄鏈接

  • 手機(jī)號接收驗(yàn)證碼

  • 只要你能收到郵箱/驗(yàn)證碼嫉鲸,就默認(rèn)你是賬號的主人

什么是授權(quán)(Authorization)

  • 用戶授予第三方應(yīng)用訪問該用戶某些資源的權(quán)限

  • 你在安裝手機(jī)應(yīng)用的時候撑蒜,APP 會詢問是否允許授予權(quán)限(訪問相冊、地理位置等權(quán)限)

  • 你在訪問微信小程序時玄渗,當(dāng)?shù)卿洉r座菠,小程序會詢問是否允許授予權(quán)限(獲取昵稱、頭像藤树、地區(qū)浴滴、性別等個人信息)

  • 實(shí)現(xiàn)授權(quán)的方式有:cookie、session岁钓、token升略、OAuth

什么是憑證(Credentials)

  • 實(shí)現(xiàn)認(rèn)證和授權(quán)的前提是需要一種媒介(證書) 來標(biāo)記訪問者的身份

  • 在戰(zhàn)國時期微王,商鞅變法,發(fā)明了照身帖品嚣。照身帖由官府發(fā)放炕倘,是一塊打磨光滑細(xì)密的竹板,上面刻有持有人的頭像和籍貫信息翰撑。國人必須持有罩旋,如若沒有就被認(rèn)為是黑戶,或者間諜之類的眶诈。

  • 在現(xiàn)實(shí)生活中涨醋,每個人都會有一張專屬的居民身份證,是用于證明持有人身份的一種法定證件逝撬。通過身份證浴骂,我們可以辦理手機(jī)卡/銀行卡/個人貸款/交通出行等等,這就是認(rèn)證的憑證宪潮。

  • 在互聯(lián)網(wǎng)應(yīng)用中溯警,一般網(wǎng)站(如掘金)會有兩種模式,游客模式和登錄模式狡相。游客模式下愧膀,可以正常瀏覽網(wǎng)站上面的文章,一旦想要點(diǎn)贊/收藏/分享文章谣光,就需要登錄或者注冊賬號。當(dāng)用戶登錄成功后芬为,服務(wù)器會給該用戶使用的瀏覽器頒發(fā)一個令牌(token)萄金,這個令牌用來表明你的身份,每次瀏覽器發(fā)送請求時會帶上這個令牌媚朦,就可以使用游客模式下無法使用的功能氧敢。

什么是 Cookie

  • HTTP 是無狀態(tài)的協(xié)議(對于事務(wù)處理沒有記憶能力,每次客戶端和服務(wù)端會話完成時询张,服務(wù)端不會保存任何會話信息):每個請求都是完全獨(dú)立的孙乖,服務(wù)端無法確認(rèn)當(dāng)前訪問者的身份信息,無法分辨上一次的請求發(fā)送者和這一次的發(fā)送者是不是同一個人份氧。所以服務(wù)器與瀏覽器為了進(jìn)行會話跟蹤(知道是誰在訪問我)唯袄,就必須主動的去維護(hù)一個狀態(tài),這個狀態(tài)用于告知服務(wù)端前后兩個請求是否來自同一瀏覽器蜗帜。而這個狀態(tài)需要通過 cookie 或者 session 去實(shí)現(xiàn)恋拷。

  • cookie 存儲在客戶端: cookie 是服務(wù)器發(fā)送到用戶瀏覽器并保存在本地的一小塊數(shù)據(jù),它會在瀏覽器下次向同一服務(wù)器再發(fā)起請求時被攜帶并發(fā)送到服務(wù)器上厅缺。

  • cookie 是不可跨域的: 每個 cookie 都會綁定單一的域名蔬顾,無法在別的域名下獲取使用宴偿,一級域名和二級域名之間是允許共享使用的靠的是 domain)

cookie 重要的屬性

image

什么是 Session

  • session 是另一種記錄服務(wù)器和客戶端會話狀態(tài)的機(jī)制

  • session 是基于 cookie 實(shí)現(xiàn)的诀豁,session 存儲在服務(wù)器端窄刘,sessionId 會被存儲到客戶端的cookie 中

image
  • session 認(rèn)證流程:

  • 用戶第一次請求服務(wù)器的時候,服務(wù)器根據(jù)用戶提交的相關(guān)信息舷胜,創(chuàng)建對應(yīng)的 Session

  • 請求返回時將此 Session 的唯一標(biāo)識信息 SessionID 返回給瀏覽器

  • 瀏覽器接收到服務(wù)器返回的 SessionID 信息后娩践,會將此信息存入到 Cookie 中,同時 Cookie 記錄此 SessionID 屬于哪個域名

  • 當(dāng)用戶第二次訪問服務(wù)器的時候逞带,請求會自動判斷此域名下是否存在 Cookie 信息欺矫,如果存在自動將 Cookie 信息也發(fā)送給服務(wù)端,服務(wù)端會從 Cookie 中獲取 SessionID展氓,再根據(jù) SessionID 查找對應(yīng)的 Session 信息穆趴,如果沒有找到說明用戶沒有登錄或者登錄失效,如果找到 Session 證明用戶已經(jīng)登錄可執(zhí)行后面操作遇汞。

根據(jù)以上流程可知未妹,SessionID 是連接 Cookie 和 Session 的一道橋梁,大部分系統(tǒng)也是根據(jù)此原理來驗(yàn)證用戶登錄狀態(tài)空入。

Cookie 和 Session 的區(qū)別

  • 安全性: Session 比 Cookie 安全络它,Session 是存儲在服務(wù)器端的,Cookie 是存儲在客戶端的歪赢。

  • 存取值的類型不同:Cookie 只支持存字符串?dāng)?shù)據(jù)化戳,想要設(shè)置其他類型的數(shù)據(jù),需要將其轉(zhuǎn)換成字符串埋凯,Session 可以存任意數(shù)據(jù)類型点楼。

  • 有效期不同: Cookie 可設(shè)置為長時間保持,比如我們經(jīng)常使用的默認(rèn)登錄功能白对,Session 一般失效時間較短掠廓,客戶端關(guān)閉(默認(rèn)情況下)或者 Session 超時都會失效。

  • 存儲大小不同: 單個 Cookie 保存的數(shù)據(jù)不能超過 4K甩恼,Session 可存儲數(shù)據(jù)遠(yuǎn)高于 Cookie蟀瞧,但是當(dāng)訪問量過多,會占用過多的服務(wù)器資源条摸。

什么是 Token(令牌)

Acesss Token

  • 訪問資源接口(API)時所需要的資源憑證

  • 簡單 token 的組成: uid(用戶唯一的身份標(biāo)識)悦污、time(當(dāng)前時間的時間戳)、sign(簽名屈溉,token 的前幾位以哈希算法壓縮成的一定長度的十六進(jìn)制字符串)

  • 特點(diǎn):

  • 服務(wù)端無狀態(tài)化塞关、可擴(kuò)展性好

  • 支持移動端設(shè)備

  • 安全

  • 支持跨程序調(diào)用

  • token 的身份驗(yàn)證流程:

image
  1. 客戶端使用用戶名跟密碼請求登錄

  2. 服務(wù)端收到請求,去驗(yàn)證用戶名與密碼

  3. 驗(yàn)證成功后子巾,服務(wù)端會簽發(fā)一個 token 并把這個 token 發(fā)送給客戶端

  4. 客戶端收到 token 以后帆赢,會把它存儲起來小压,比如放在 cookie 里或者 localStorage 里

  5. 客戶端每次向服務(wù)端請求資源的時候需要帶著服務(wù)端簽發(fā)的 token

  6. 服務(wù)端收到請求,然后去驗(yàn)證客戶端請求里面帶著的 token 椰于,如果驗(yàn)證成功怠益,就向客戶端返回請求的數(shù)據(jù)

  • 每一次請求都需要攜帶 token,需要把 token 放到 HTTP 的 Header 里

  • 基于 token 的用戶認(rèn)證是一種服務(wù)端無狀態(tài)的認(rèn)證方式瘾婿,服務(wù)端不用存放 token 數(shù)據(jù)蜻牢。用解析 token 的計(jì)算時間換取 session 的存儲空間,從而減輕服務(wù)器的壓力偏陪,減少頻繁的查詢數(shù)據(jù)庫

  • token 完全由應(yīng)用管理抢呆,所以它可以避開同源策略

Refresh Token

  • 另外一種 token——refresh token

  • refresh token 是專用于刷新 access token 的 token。如果沒有 refresh token笛谦,也可以刷新 access token抱虐,但每次刷新都要用戶輸入登錄用戶名與密碼,會很麻煩饥脑。有了 refresh token恳邀,可以減少這個麻煩,客戶端直接用 refresh token 去更新 access token灶轰,無需用戶進(jìn)行額外的操作谣沸。

image
  • Access Token 的有效期比較短,當(dāng) Acesss Token 由于過期而失效時笋颤,使用 Refresh Token 就可以獲取到新的 Token乳附,如果 Refresh Token 也失效了,用戶就只能重新登錄了伴澄。

  • Refresh Token 及過期時間是存儲在服務(wù)器的數(shù)據(jù)庫中许溅,只有在申請新的 Acesss Token 時才會驗(yàn)證,不會對業(yè)務(wù)接口響應(yīng)時間造成影響秉版,也不需要向 Session 一樣一直保持在內(nèi)存中以應(yīng)對大量的請求。

Token 和 Session 的區(qū)別

  • Session 是一種記錄服務(wù)器和客戶端會話狀態(tài)的機(jī)制茬祷,使服務(wù)端有狀態(tài)化清焕,可以記錄會話信息。而 Token 是令牌祭犯,訪問資源接口(API)時所需要的資源憑證秸妥。Token 使服務(wù)端無狀態(tài)化,不會存儲會話信息沃粗。

  • Session 和 Token 并不矛盾粥惧,作為身份認(rèn)證 Token 安全性比 Session 好,因?yàn)槊恳粋€請求都有簽名還能防止監(jiān)聽以及重放攻擊最盅,而 Session 就必須依賴鏈路層來保障通訊安全了突雪。如果你需要實(shí)現(xiàn)有狀態(tài)的會話起惕,仍然可以增加 Session 來在服務(wù)器端保存一些狀態(tài)。

  • 所謂 Session 認(rèn)證只是簡單的把 User 信息存儲到 Session 里咏删,因?yàn)?SessionID 的不可預(yù)測性惹想,暫且認(rèn)為是安全的。而 Token 督函,如果指的是 OAuth Token 或類似的機(jī)制的話嘀粱,提供的是 認(rèn)證 和 授權(quán) ,認(rèn)證是針對用戶辰狡,授權(quán)是針對 App 锋叨。其目的是讓某 App 有權(quán)利訪問某用戶的信息。這里的 Token 是唯一的宛篇。不可以轉(zhuǎn)移到其它 App上娃磺,也不可以轉(zhuǎn)到其它用戶上。Session 只提供一種簡單的認(rèn)證些己,即只要有此 SessionID 豌鸡,即認(rèn)為有此 User 的全部權(quán)利。是需要嚴(yán)格保密的段标,這個數(shù)據(jù)應(yīng)該只保存在站方涯冠,不應(yīng)該共享給其它網(wǎng)站或者第三方 App。所以簡單來說:如果你的用戶數(shù)據(jù)可能需要和第三方共享逼庞,或者允許第三方調(diào)用 API 接口蛇更,用 Token 。如果永遠(yuǎn)只是自己的網(wǎng)站赛糟,自己的 App派任,用什么就無所謂了。

什么是 JWT

  • JSON Web Token(簡稱 JWT)是目前最流行的跨域認(rèn)證解決方案璧南。

  • 是一種認(rèn)證授權(quán)機(jī)制掌逛。

  • JWT 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于 JSON 的開放標(biāo)準(zhǔn)(RFC 7519)。JWT 的聲明一般被用來在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息司倚,以便于從資源服務(wù)器獲取資源豆混。比如用在用戶登錄上。

  • 可以使用 HMAC 算法或者是 RSA 的公/私秘鑰對 JWT 進(jìn)行簽名动知。因?yàn)閿?shù)字簽名的存在皿伺,這些傳遞的信息是可信的。

  • 阮一峰老師的 JSON Web Token 入門教程 講的非常通俗易懂盒粮,這里就不再班門弄斧了

生成 JWT

JWT 的原理

image
  • JWT 認(rèn)證流程:

  • 用戶輸入用戶名/密碼登錄鸵鸥,服務(wù)端認(rèn)證成功后,會返回給客戶端一個 JWT

  • 客戶端將 token 保存到本地(通常使用 localstorage丹皱,也可以使用 cookie)

  • 當(dāng)用戶希望訪問一個受保護(hù)的路由或者資源的時候妒穴,需要請求頭的 Authorization 字段中使用Bearer 模式添加 JWT宋税,其內(nèi)容看起來是下面這樣

Authorization: Bearer <token>
  • 服務(wù)端的保護(hù)路由將會檢查請求頭 Authorization 中的 JWT 信息,如果合法宰翅,則允許用戶的行為

  • 因?yàn)?JWT 是自包含的(內(nèi)部包含了一些會話信息)弃甥,因此減少了需要查詢數(shù)據(jù)庫的需要

  • 因?yàn)?JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服務(wù)而不需要擔(dān)心跨域資源共享問題(CORS)

  • 因?yàn)橛脩舻臓顟B(tài)不再存儲在服務(wù)端的內(nèi)存中汁讼,所以這是一種無狀態(tài)的認(rèn)證機(jī)制

JWT 的使用方式

  • 客戶端收到服務(wù)器返回的 JWT淆攻,可以儲存在 Cookie 里面,也可以儲存在 localStorage嘿架。

方式一

  • 當(dāng)用戶希望訪問一個受保護(hù)的路由或者資源的時候瓶珊,可以把它放在 Cookie 里面自動發(fā)送,但是這樣不能跨域耸彪,所以更好的做法是放在 HTTP 請求頭信息的 Authorization 字段里伞芹,使用 Bearer 模式添加 JWT。

    GET /calendar/v1/events
    
  • 用戶的狀態(tài)不會存儲在服務(wù)端的內(nèi)存中蝉娜,這是一種 無狀態(tài)的認(rèn)證機(jī)制

  • 服務(wù)端的保護(hù)路由將會檢查請求頭 Authorization 中的 JWT 信息唱较,如果合法,則允許用戶的行為召川。

  • 由于 JWT 是自包含的南缓,因此減少了需要查詢數(shù)據(jù)庫的需要

  • JWT 的這些特性使得我們可以完全依賴其無狀態(tài)的特性提供數(shù)據(jù) API 服務(wù),甚至是創(chuàng)建一個下載流服務(wù)荧呐。

  • 因?yàn)?JWT 并不使用 Cookie 汉形,所以你可以使用任何域名提供你的 API 服務(wù)而不需要擔(dān)心跨域資源共享問題(CORS)

方式二

  • 跨域的時候,可以把 JWT 放在 POST 請求的數(shù)據(jù)體里倍阐。

方式三

  • 通過 URL 傳輸
http://www.example.com/user?token=xxx

項(xiàng)目中使用 JWT

項(xiàng)目地址:https://github.com/yjdjiayou/jwt-demo

Token 和 JWT 的區(qū)別

相同:

  • 都是訪問資源的令牌

  • 都可以記錄用戶的信息

  • 都是使服務(wù)端無狀態(tài)化

  • 都是只有驗(yàn)證成功后概疆,客戶端才能訪問服務(wù)端上受保護(hù)的資源

區(qū)別:

  • Token:服務(wù)端驗(yàn)證客戶端發(fā)送過來的 Token 時,還需要查詢數(shù)據(jù)庫獲取用戶信息峰搪,然后驗(yàn)證 Token 是否有效岔冀。

  • JWT:將 Token 和 Payload 加密后存儲于客戶端,服務(wù)端只需要使用密鑰解密進(jìn)行校驗(yàn)(校驗(yàn)也是 JWT 自己實(shí)現(xiàn)的)即可概耻,不需要查詢或者減少查詢數(shù)據(jù)庫楣颠,因?yàn)?JWT 自包含了用戶信息和加密的數(shù)據(jù)。

常見的前后端鑒權(quán)方式

  1. Session-Cookie

  2. Token 驗(yàn)證(包括 JWT咐蚯,SSO)

  3. OAuth2.0(開放授權(quán))

常見的加密算法

image
  • 哈希算法(Hash Algorithm)又稱散列算法、散列函數(shù)弄贿、哈希函數(shù)春锋,是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。哈希算法將數(shù)據(jù)重新打亂混合差凹,重新創(chuàng)建一個哈希值期奔。

  • 哈希算法主要用來保障數(shù)據(jù)真實(shí)性(即完整性)侧馅,即發(fā)信人將原始消息和哈希值一起發(fā)送,收信人通過相同的哈希函數(shù)來校驗(yàn)原始數(shù)據(jù)是否真實(shí)呐萌。

  • 哈希算法通常有以下幾個特點(diǎn):

  • 2 的 128 次方為 340282366920938463463374607431768211456馁痴,也就是 10 的 39 次方級別

  • 2 的 160 次方為 1.4615016373309029182036848327163e+48,也就是 10 的 48 次方級別

  • 2 的 256 次方為 1.1579208923731619542357098500869 × 10 的 77 次方肺孤,也就是 10 的 77 次方

  • 正像快速:原始數(shù)據(jù)可以快速計(jì)算出哈希值

  • 逆向困難:通過哈希值基本不可能推導(dǎo)出原始數(shù)據(jù)

  • 輸入敏感:原始數(shù)據(jù)只要有一點(diǎn)變動罗晕,得到的哈希值差別很大

  • 沖突避免:很難找到不同的原始數(shù)據(jù)得到相同的哈希值,宇宙中原子數(shù)大約在 10 的 60 次方到 80 次方之間赠堵,所以 2 的 256 次方有足夠的空間容納所有的可能小渊,算法好的情況下沖突碰撞的概率很低:

注意:

  1. 以上不能保證數(shù)據(jù)被惡意篡改,原始數(shù)據(jù)和哈希值都可能被惡意篡改茫叭,要保證不被篡改酬屉,可以使用RSA 公鑰私鑰方案,再配合哈希值揍愁。

  2. 哈希算法主要用來防止計(jì)算機(jī)傳輸過程中的錯誤呐萨,早期計(jì)算機(jī)通過前 7 位數(shù)據(jù)第 8 位奇偶校驗(yàn)碼來保障(12.5% 的浪費(fèi)效率低),對于一段數(shù)據(jù)或文件莽囤,通過哈希算法生成 128bit 或者 256bit 的哈希值谬擦,如果校驗(yàn)有問題就要求重傳。

常見問題

使用 cookie 時需要考慮的問題

  • 因?yàn)榇鎯υ诳蛻舳怂傅牵菀妆豢蛻舳舜鄹那犹耄褂们靶枰?yàn)證合法性

  • 不要存儲敏感數(shù)據(jù),比如用戶密碼饵沧,賬戶余額

  • 使用 httpOnly 在一定程度上提高安全性

  • 盡量減少 cookie 的體積锨络,能存儲的數(shù)據(jù)量不能超過 4kb

  • 設(shè)置正確的 domain 和 path,減少數(shù)據(jù)傳輸

  • cookie 無法跨域

  • 一個瀏覽器針對一個網(wǎng)站最多存 20 個Cookie狼牺,瀏覽器一般只允許存放 300 個Cookie

  • 移動端對 cookie 的支持不是很好羡儿,而 session 需要基于 cookie 實(shí)現(xiàn),所以移動端常用的是 token

使用 session 時需要考慮的問題

  • 將 session 存儲在服務(wù)器里面是钥,當(dāng)用戶同時在線量比較多時掠归,這些 session 會占據(jù)較多的內(nèi)存,需要在服務(wù)端定期的去清理過期的 session

  • 當(dāng)網(wǎng)站采用集群部署的時候悄泥,會遇到多臺 web 服務(wù)器之間如何做 session 共享的問題虏冻。因?yàn)?session 是由單個服務(wù)器創(chuàng)建的,但是處理用戶請求的服務(wù)器不一定是那個創(chuàng)建 session 的服務(wù)器弹囚,那么該服務(wù)器就無法拿到之前已經(jīng)放入到 session 中的登錄憑證之類的信息了厨相。

  • 當(dāng)多個應(yīng)用要共享 session 時,除了以上問題,還會遇到跨域問題蛮穿,因?yàn)椴煌膽?yīng)用可能部署的主機(jī)不一樣庶骄,需要在各個應(yīng)用做好 cookie 跨域的處理。

  • sessionId 是存儲在 cookie 中的践磅,假如瀏覽器禁止 cookie 或不支持 cookie 怎么辦单刁? 一般會把 sessionId 跟在 url 參數(shù)后面即重寫 url干跛,所以 session 不一定非得需要靠 cookie 實(shí)現(xiàn)

  • 移動端對 cookie 的支持不是很好梆暖,而 session 需要基于 cookie 實(shí)現(xiàn)昔园,所以移動端常用的是 token

使用 token 時需要考慮的問題

  • 如果你認(rèn)為用數(shù)據(jù)庫來存儲 token 會導(dǎo)致查詢時間太長诊沪,可以選擇放在內(nèi)存當(dāng)中凫佛。比如 redis 很適合你對 token 查詢的需求罐监。

  • token 完全由應(yīng)用管理裂问,所以它可以避開同源策略

  • token 可以避免 CSRF 攻擊(因?yàn)椴恍枰?cookie 了)

  • 移動端對 cookie 的支持不是很好宋雏,而 session 需要基于 cookie 實(shí)現(xiàn)喇聊,所以移動端常用的是 token

使用 JWT 時需要考慮的問題

  • 因?yàn)?JWT 并不依賴 Cookie 的恍风,所以你可以使用任何域名提供你的 API 服務(wù)而不需要擔(dān)心跨域資源共享問題(CORS)

  • JWT 默認(rèn)是不加密,但也是可以加密的誓篱。生成原始 Token 以后朋贬,可以用密鑰再加密一次。

  • JWT 不加密的情況下窜骄,不能將秘密數(shù)據(jù)寫入 JWT锦募。

  • JWT 不僅可以用于認(rèn)證,也可以用于交換信息邻遏。有效使用 JWT糠亩,可以降低服務(wù)器查詢數(shù)據(jù)庫的次數(shù)。

  • JWT 最大的優(yōu)勢是服務(wù)器不再需要存儲 Session准验,使得服務(wù)器認(rèn)證鑒權(quán)業(yè)務(wù)可以方便擴(kuò)展赎线。但這也是 JWT 最大的缺點(diǎn):由于服務(wù)器不需要存儲 Session 狀態(tài),因此使用過程中無法廢棄某個 Token 或者更改 Token 的權(quán)限糊饱。也就是說一旦 JWT 簽發(fā)了垂寥,到期之前就會始終有效,除非服務(wù)器部署額外的邏輯另锋。

  • JWT 本身包含了認(rèn)證信息滞项,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限夭坪。為了減少盜用文判,JWT的有效期應(yīng)該設(shè)置得比較短。對于一些比較重要的權(quán)限室梅,使用時應(yīng)該再次對用戶進(jìn)行認(rèn)證戏仓。

  • JWT 適合一次性的命令認(rèn)證潭流,頒發(fā)一個有效期極短的 JWT,即使暴露了危險也很小柜去,由于每次操作都會生成新的 JWT,因此也沒必要保存 JWT拆宛,真正實(shí)現(xiàn)無狀態(tài)嗓奢。

  • 為了減少盜用,JWT 不應(yīng)該使用 HTTP 協(xié)議明碼傳輸浑厚,要使用 HTTPS 協(xié)議傳輸股耽。

使用加密算法時需要考慮的問題

  • 絕不要以明文存儲密碼

  • 永遠(yuǎn)使用 哈希算法 來處理密碼,絕不要使用 Base64 或其他編碼方式來存儲密碼钳幅,這和以明文存儲密碼是一樣的物蝙,使用哈希,而不要使用編碼敢艰。編碼以及加密诬乞,都是雙向的過程,而密碼是保密的钠导,應(yīng)該只被它的所有者知道震嫉, 這個過程必須是單向的。哈希正是用于做這個的牡属,從來沒有解哈希這種說法票堵, 但是編碼就存在解碼,加密就存在解密逮栅。

  • 絕不要使用弱哈香彩疲或已被破解的哈希算法,像 MD5 或 SHA1 措伐,只使用強(qiáng)密碼哈希算法特纤。

  • 絕不要以明文形式顯示或發(fā)送密碼,即使是對密碼的所有者也應(yīng)該這樣废士。如果你需要 “忘記密碼” 的功能叫潦,可以隨機(jī)生成一個新的 一次性的(這點(diǎn)很重要)密碼,然后把這個密碼發(fā)送給用戶官硝。

分布式架構(gòu)下 session 共享方案

1. session 復(fù)制

  • 任何一個服務(wù)器上的 session 發(fā)生改變(增刪改)矗蕊,該節(jié)點(diǎn)會把這個 session 的所有內(nèi)容序列化,然后廣播給所有其它節(jié)點(diǎn)氢架,不管其他服務(wù)器需不需要 session 傻咖,以此來保證 session 同步

優(yōu)點(diǎn): 可容錯,各個服務(wù)器間 session 能夠?qū)崟r響應(yīng)岖研。
缺點(diǎn): 會對網(wǎng)絡(luò)負(fù)荷造成一定壓力卿操,如果 session 量大的話可能會造成網(wǎng)絡(luò)堵塞警检,拖慢服務(wù)器性能。

2. 粘性 session /IP 綁定策略

  • 采用 Ngnix 中的 ip_hash 機(jī)制害淤,將某個 ip的所有請求都定向到同一臺服務(wù)器上扇雕,即將用戶與服務(wù)器綁定。 用戶第一次請求時窥摄,負(fù)載均衡器將用戶的請求轉(zhuǎn)發(fā)到了 A 服務(wù)器上镶奉,如果負(fù)載均衡器設(shè)置了粘性 session 的話,那么用戶以后的每次請求都會轉(zhuǎn)發(fā)到 A 服務(wù)器上崭放,相當(dāng)于把用戶和 A 服務(wù)器粘到了一塊哨苛,這就是粘性 session 機(jī)制。

優(yōu)點(diǎn): 簡單币砂,不需要對 session 做任何處理建峭。
缺點(diǎn): 缺乏容錯性,如果當(dāng)前訪問的服務(wù)器發(fā)生故障决摧,用戶被轉(zhuǎn)移到第二個服務(wù)器上時亿蒸,他的 session 信息都將失效。
適用場景: 發(fā)生故障對客戶產(chǎn)生的影響較忻刍铡祝懂;服務(wù)器發(fā)生故障是低概率事件 。
實(shí)現(xiàn)方式: 以 Nginx 為例拘鞋,在 upstream 模塊配置 ip_hash 屬性即可實(shí)現(xiàn)粘性 session砚蓬。

3. session 共享(常用)

  • 使用分布式緩存方案比如 Memcached 、Redis 來緩存 session盆色,但是要求 Memcached 或 Redis 必須是集群

  • 把 session 放到 Redis 中存儲灰蛙,雖然架構(gòu)上變得復(fù)雜,并且需要多訪問一次 Redis 隔躲,但是這種方案帶來的好處也是很大的:

  • 實(shí)現(xiàn)了 session 共享摩梧;

  • 可以水平擴(kuò)展(增加 Redis 服務(wù)器);

  • 服務(wù)器重啟 session 不丟失(不過也要注意 session 在 Redis 中的刷新/失效機(jī)制)宣旱;

  • 不僅可以跨服務(wù)器 session 共享仅父,甚至可以跨平臺(例如網(wǎng)頁端和 APP 端)

image

4. session 持久化

  • 將 session 存儲到數(shù)據(jù)庫中,保證 session 的持久化

優(yōu)點(diǎn): 服務(wù)器出現(xiàn)問題浑吟,session 不會丟失
缺點(diǎn): 如果網(wǎng)站的訪問量很大笙纤,把 session 存儲到數(shù)據(jù)庫中,會對數(shù)據(jù)庫造成很大壓力组力,還需要增加額外的開銷維護(hù)數(shù)據(jù)庫省容。

只要關(guān)閉瀏覽器 ,session 真的就消失了燎字?

不對腥椒。對 session 來說阿宅,除非程序通知服務(wù)器刪除一個 session,否則服務(wù)器會一直保留笼蛛,程序一般都是在用戶做 log off 的時候發(fā)個指令去刪除 session洒放。
然而瀏覽器從來不會主動在關(guān)閉之前通知服務(wù)器它將要關(guān)閉,因此服務(wù)器根本不會有機(jī)會知道瀏覽器已經(jīng)關(guān)閉滨砍,之所以會有這種錯覺拉馋,是大部分 session 機(jī)制都使用會話 cookie 來保存 session id,而關(guān)閉瀏覽器后這個 session id 就消失了惨好,再次連接服務(wù)器時也就無法找到原來的 session。如果服務(wù)器設(shè)置的 cookie 被保存在硬盤上随闺,或者使用某種手段改寫瀏覽器發(fā)出的 HTTP 請求頭日川,把原來的 session id 發(fā)送給服務(wù)器,則再次打開瀏覽器仍然能夠打開原來的 session矩乐。
恰恰是由于關(guān)閉瀏覽器不會導(dǎo)致 session 被刪除龄句,迫使服務(wù)器為 session 設(shè)置了一個失效時間,當(dāng)距離客戶端上一次使用 session 的時間超過這個失效時間時散罕,服務(wù)器就認(rèn)為客戶端已經(jīng)停止了活動分歇,才會把 session 刪除以節(jié)省存儲空間。

項(xiàng)目地址

https://github.com/yjdjiayou/jwt-demo

后語

  • 本文只是基于自己的理解講了理論知識欧漱,因?yàn)閷蠖?算法知識不是很熟职抡,如有謬誤,還請告知误甚,萬分感謝缚甩!

  • 如果本文對你有所幫助,還請點(diǎn)個贊~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末窑邦,一起剝皮案震驚了整個濱河市擅威,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冈钦,老刑警劉巖郊丛,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞧筛,居然都是意外死亡厉熟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門驾窟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庆猫,“玉大人,你說我怎么就攤上這事绅络≡屡啵” “怎么了嘁字?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杉畜。 經(jīng)常有香客問我纪蜒,道長,這世上最難降的妖魔是什么此叠? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任纯续,我火速辦了婚禮,結(jié)果婚禮上灭袁,老公的妹妹穿的比我還像新娘猬错。我一直安慰自己,他們只是感情好茸歧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布倦炒。 她就那樣靜靜地躺著,像睡著了一般软瞎。 火紅的嫁衣襯著肌膚如雪逢唤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天涤浇,我揣著相機(jī)與錄音鳖藕,去河邊找鬼。 笑死只锭,一個胖子當(dāng)著我的面吹牛著恩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜻展,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼页滚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了铺呵?” 一聲冷哼從身側(cè)響起裹驰,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎片挂,沒想到半個月后幻林,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡音念,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年沪饺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闷愤。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡整葡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讥脐,到底是詐尸還是另有隱情遭居,我是刑警寧澤啼器,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站俱萍,受9級特大地震影響端壳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枪蘑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一损谦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岳颇,春花似錦照捡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掂摔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赢赊,已是汗流浹背乙漓。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留释移,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓玩讳,卻偏偏與公主長得像涩蜘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子熏纯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354