日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

计算机网络——cookie、session、token原理

發(fā)布時(shí)間:2024/1/8 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算机网络——cookie、session、token原理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

摘要

HTTP是無(wú)狀態(tài)的Web服務(wù)器,一次對(duì)話(huà)完成后下一次對(duì)話(huà)完全不知道上一次對(duì)話(huà)發(fā)生了什么,但是隨著網(wǎng)絡(luò)的不斷發(fā)展,比如電商中的購(gòu)物車(chē)只有記住了用戶(hù)的身份才能夠執(zhí)行接下來(lái)的一系列動(dòng)作。所以此時(shí)就需要我們無(wú)狀態(tài)的服務(wù)器記住一些事情。由此就產(chǎn)生了cookie和session技術(shù)。本博文主要講述HTTP中Cookie/Session/token原理以及相關(guān)知識(shí),同時(shí)也將延展到權(quán)限管理對(duì)于token和鑒權(quán)相關(guān)原理的知識(shí)。

一、Cookie的原理

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

  • cookie 存儲(chǔ)在客戶(hù)端: cookie 是服務(wù)器發(fā)送到用戶(hù)瀏覽器并保存在本地的一小塊數(shù)據(jù),它會(huì)在瀏覽器下次向同一服務(wù)器再發(fā)起請(qǐng)求時(shí)被攜帶并發(fā)送到服務(wù)器上。
  • cookie 是不可跨域的: 每個(gè) cookie 都會(huì)綁定單一的域名,無(wú)法在別的域名下獲取使用,一級(jí)域名和二級(jí)域名之間是允許共享使用的(靠的是 domain)。

二、Session的原理

session 是另一種記錄服務(wù)器和客戶(hù)端會(huì)話(huà)狀態(tài)的機(jī)制。session 是基于 cookie 實(shí)現(xiàn)的,session 存儲(chǔ)在服務(wù)器端,sessionId 會(huì)被存儲(chǔ)到客戶(hù)端的cookie 中。

session 認(rèn)證流程:

  • 用戶(hù)第一次請(qǐng)求服務(wù)器的時(shí)候,服務(wù)器根據(jù)用戶(hù)提交的相關(guān)信息,創(chuàng)建對(duì)應(yīng)的 Session
  • 請(qǐng)求返回時(shí)將此 Session 的唯一標(biāo)識(shí)信息 SessionID 返回給瀏覽器
  • 瀏覽器接收到服務(wù)器返回的 SessionID 信息后,會(huì)將此信息存入到 Cookie 中,同時(shí) Cookie 記錄此 SessionID 屬于哪個(gè)域名
  • 當(dāng)用戶(hù)第二次訪問(wèn)服務(wù)器的時(shí)候,請(qǐng)求會(huì)自動(dòng)判斷此域名下是否存在 Cookie 信息,如果存在自動(dòng)將 Cookie 信息也發(fā)送給服務(wù)端,服務(wù)端會(huì)從 Cookie 中獲取 SessionID,再根據(jù) SessionID 查找對(duì)應(yīng)的 Session 信息,如果沒(méi)有找到說(shuō)明用戶(hù)沒(méi)有登錄或者登錄失效,如果找到 Session 證明用戶(hù)已經(jīng)登錄可執(zhí)行后面操作。

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

session和cookie區(qū)別:

  • 數(shù)據(jù)存放位置不同:Session數(shù)據(jù)是存在服務(wù)器中的,cookie數(shù)據(jù)存放在瀏覽器當(dāng)中。
  • 安全程度不同:cookie放在服務(wù)器中不是很安全,session放在服務(wù)器中,相對(duì)安全。
  • 性能使用程度不同:session放在服務(wù)器上,訪問(wèn)增多會(huì)占用服務(wù)器的性能;考慮到減輕服務(wù)器性能方面,應(yīng)使用cookie。
  • 數(shù)據(jù)存儲(chǔ)大小不同:單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,session存儲(chǔ)在服務(wù)端,根據(jù)服務(wù)器大小來(lái)定。

三、Token令牌原理

訪問(wèn)資源接口(API)時(shí)所需要的資源憑證。簡(jiǎn)單 token 的組成: uid(用戶(hù)唯一的身份標(biāo)識(shí))、time(當(dāng)前時(shí)間的時(shí)間戳)、sign(簽名,token 的前幾位以哈希算法壓縮成的一定長(zhǎng)度的十六進(jìn)制字符串)。特點(diǎn):服務(wù)端無(wú)狀態(tài)化、可擴(kuò)展性好,支持移動(dòng)端設(shè)備,安全,支持跨程序調(diào)用。

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

  • 客戶(hù)端使用用戶(hù)名跟密碼請(qǐng)求登錄
  • 服務(wù)端收到請(qǐng)求,去驗(yàn)證用戶(hù)名與密碼
  • 驗(yàn)證成功后,服務(wù)端會(huì)簽發(fā)一個(gè) token 并把這個(gè) token 發(fā)送給客戶(hù)端
  • 客戶(hù)端收到 token 以后,會(huì)把它存儲(chǔ)起來(lái),比如放在 cookie 里或者 localStorage 里
  • 客戶(hù)端每次向服務(wù)端請(qǐng)求資源的時(shí)候需要帶著服務(wù)端簽發(fā)的 token
  • 服務(wù)端收到請(qǐng)求,然后去驗(yàn)證客戶(hù)端請(qǐng)求里面帶著的 token ,如果驗(yàn)證成功,就向客戶(hù)端返回請(qǐng)求的數(shù)據(jù)
  • 每一次請(qǐng)求都需要攜帶 token,需要把 token 放到 HTTP 的 Header 里,基于token的用戶(hù)認(rèn)證是一種服務(wù)端無(wú)狀態(tài)的認(rèn)證方式,服務(wù)端不用存放 token 數(shù)據(jù)。用解析token的計(jì)算時(shí)間換取session 的存儲(chǔ)空間,從減輕服務(wù)器的壓力,減少頻繁的查詢(xún)數(shù)據(jù)庫(kù),token完全由應(yīng)用管理,所以它可以避開(kāi)同源策略。

    另外一種 token——refresh token,refresh token 是專(zhuān)用于刷新 access token 的 token。如果沒(méi)有 refresh token,也可以刷新 access token,但每次刷新都要用戶(hù)輸入登錄用戶(hù)名與密碼,會(huì)很麻煩。有了 refresh token,可以減少這個(gè)麻煩,客戶(hù)端直接用 refresh token 去更新 access token,無(wú)需用戶(hù)進(jìn)行額外的操作。

    • ?Access Token 的有效期比較短,當(dāng) Acesss Token 由于過(guò)期而失效時(shí),使用 Refresh Token 就可以獲取到新的 Token,如果 Refresh Token 也失效了,用戶(hù)就只能重新登錄了。
    • Refresh Token 及過(guò)期時(shí)間是存儲(chǔ)在服務(wù)器的數(shù)據(jù)庫(kù)中,只有在申請(qǐng)新的 Acesss Token 時(shí)才會(huì)驗(yàn)證,不會(huì)對(duì)業(yè)務(wù)接口響應(yīng)時(shí)間造成影響,也不需要向 Session 一樣一直保持在內(nèi)存中以應(yīng)對(duì)大量的請(qǐng)求。

    token和session區(qū)別:

    • Session 是一種記錄服務(wù)器和客戶(hù)端會(huì)話(huà)狀態(tài)的機(jī)制,使服務(wù)端有狀態(tài)化,可以記錄會(huì)話(huà)信息。而 Token 是令牌,訪問(wèn)資源接口(API)時(shí)所需要的資源憑證。Token 使服務(wù)端無(wú)狀態(tài)化,不會(huì)存儲(chǔ)會(huì)話(huà)信息。
    • Session 和 Token 并不矛盾,作為身份認(rèn)證 Token 安全性比 Session 好,因?yàn)槊恳粋€(gè)請(qǐng)求都有簽名還能防止監(jiān)聽(tīng)以及重放攻擊,而 Session 就必須依賴(lài)鏈路層來(lái)保障通訊安全了。如果你需要實(shí)現(xiàn)有狀態(tài)的會(huì)話(huà),仍然可以增加 Session 來(lái)在服務(wù)器端保存一些狀態(tài)。
    • 所謂 Session 認(rèn)證只是簡(jiǎn)單的把 User 信息存儲(chǔ)到 Session 里,因?yàn)?SessionID 的不可預(yù)測(cè)性,暫且認(rèn)為是安全的。而 Token ,如果指的是 OAuth Token 或類(lèi)似的機(jī)制的話(huà),提供的是 認(rèn)證 和 授權(quán) ,認(rèn)證是針對(duì)用戶(hù),授權(quán)是針對(duì) App 。其目的是讓某 App 有權(quán)利訪問(wèn)某用戶(hù)的信息。這里的 Token 是唯一的。不可以轉(zhuǎn)移到其它 App上,也不可以轉(zhuǎn)到其它用戶(hù)上。Session 只提供一種簡(jiǎn)單的認(rèn)證,即只要有此 SessionID ,即認(rèn)為有此 User 的全部權(quán)利。是需要嚴(yán)格保密的,這個(gè)數(shù)據(jù)應(yīng)該只保存在站方,不應(yīng)該共享給其它網(wǎng)站或者第三方 App。所以簡(jiǎn)單來(lái)說(shuō):如果你的用戶(hù)數(shù)據(jù)可能需要和第三方共享,或者允許第三方調(diào)用 API 接口,用 Token 。如果永遠(yuǎn)只是自己的網(wǎng)站,自己的 App,用什么就無(wú)所謂了。

    四、權(quán)限校驗(yàn)解決方案

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

    • 通俗地講就是驗(yàn)證當(dāng)前用戶(hù)的身份,證明“你是你自己”(比如:你每天上下班打卡,都需要通過(guò)指紋打卡,當(dāng)你的指紋和系統(tǒng)里錄入的指紋相匹配時(shí),就打卡成功)
    • 互聯(lián)網(wǎng)中的認(rèn)證:
      • 用戶(hù)名密碼登錄
      • 郵箱發(fā)送登錄鏈接
      • 手機(jī)號(hào)接收驗(yàn)證碼
      • 只要你能收到郵箱/驗(yàn)證碼,就默認(rèn)你是賬號(hào)的主人

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

    • 用戶(hù)授予第三方應(yīng)用訪問(wèn)該用戶(hù)某些資源的權(quán)限
      • 你在安裝手機(jī)應(yīng)用的時(shí)候,APP 會(huì)詢(xún)問(wèn)是否允許授予權(quán)限(訪問(wèn)相冊(cè)、地理位置等權(quán)限)
      • 你在訪問(wèn)微信小程序時(shí),當(dāng)?shù)卿洉r(shí),小程序會(huì)詢(xún)問(wèn)是否允許授予權(quán)限(獲取昵稱(chēng)、頭像、地區(qū)、性別等個(gè)人信息)
    • 實(shí)現(xiàn)授權(quán)的方式有:cookie、session、token、OAuth

    4.4 什么是憑證(Credentials)

    • 實(shí)現(xiàn)認(rèn)證和授權(quán)的前提是需要一種媒介(證書(shū)) 來(lái)標(biāo)記訪問(wèn)者的身份
      • 在現(xiàn)實(shí)生活中,每個(gè)人都會(huì)有一張專(zhuān)屬的居民身份證,是用于證明持有人身份的一種法定證件。通過(guò)身份證,我們可以辦理手機(jī)卡/銀行卡/個(gè)人貸款/交通出行等等,這就是認(rèn)證的憑證。
      • 在互聯(lián)網(wǎng)應(yīng)用中,一般網(wǎng)站會(huì)有兩種模式,游客模式和登錄模式。游客模式下,可以正常瀏覽網(wǎng)站上面的文章,一旦想要點(diǎn)贊/收藏/分享文章,就需要登錄或者注冊(cè)賬號(hào)。當(dāng)用戶(hù)登錄成功后,服務(wù)器會(huì)給該用戶(hù)使用的瀏覽器頒發(fā)一個(gè)令牌(token),這個(gè)令牌用來(lái)表明你的身份,每次瀏覽器發(fā)送請(qǐng)求時(shí)會(huì)帶上這個(gè)令牌,就可以使用游客模式下無(wú)法使用的功能。

    4.5 什么是 JWT

    • JSON Web Token(簡(jiǎn)稱(chēng) JWT)是目前最流行的跨域認(rèn)證解決方案。
    • 是一種認(rèn)證授權(quán)機(jī)制
    • JWT 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于 JSON 的開(kāi)放標(biāo)準(zhǔn)(RFC 7519)。JWT 的聲明一般被用來(lái)在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶(hù)身份信息,以便于從資源服務(wù)器獲取資源。比如用在用戶(hù)登錄上。
    • 可以使用 HMAC 算法或者是 RSA 的公/私秘鑰對(duì) JWT 進(jìn)行簽名。因?yàn)閿?shù)字簽名的存在,這些傳遞的信息是可信的。

    • JWT 認(rèn)證流程:
      • 用戶(hù)輸入用戶(hù)名/密碼登錄,服務(wù)端認(rèn)證成功后,會(huì)返回給客戶(hù)端一個(gè) JWT
      • 客戶(hù)端將 token 保存到本地(通常使用 localstorage,也可以使用 cookie)
      • 當(dāng)用戶(hù)希望訪問(wèn)一個(gè)受保護(hù)的路由或者資源的時(shí)候,需要請(qǐng)求頭的 Authorization 字段中使用Bearer 模式添加 JWT,其內(nèi)容看起來(lái)是下面這樣
    Authorization: Bearer <token>
    • 服務(wù)端的保護(hù)路由將會(huì)檢查請(qǐng)求頭 Authorization 中的 JWT 信息,如果合法,則允許用戶(hù)的行為
    • 因?yàn)?JWT 是自包含的(內(nèi)部包含了一些會(huì)話(huà)信息),因此減少了需要查詢(xún)數(shù)據(jù)庫(kù)的需要
    • 因?yàn)?JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服務(wù)而不需要擔(dān)心跨域資源共享問(wèn)題(CORS)
    • 因?yàn)橛脩?hù)的狀態(tài)不再存儲(chǔ)在服務(wù)端的內(nèi)存中,所以這是一種無(wú)狀態(tài)的認(rèn)證機(jī)制

    4.6 JWT 的使用方式

    客戶(hù)端收到服務(wù)器返回的 JWT,可以?xún)?chǔ)存在 Cookie 里面,也可以?xún)?chǔ)存在 localStorage。

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

    GET /calendar/v1/events Host: api.example.com Authorization: Bearer <token>
    • 用戶(hù)的狀態(tài)不會(huì)存儲(chǔ)在服務(wù)端的內(nèi)存中,這是一種 無(wú)狀態(tài)的認(rèn)證機(jī)制
      • 服務(wù)端的保護(hù)路由將會(huì)檢查請(qǐng)求頭 Authorization 中的 JWT 信息,如果合法,則允許用戶(hù)的行為。
      • 由于 JWT 是自包含的,因此減少了需要查詢(xún)數(shù)據(jù)庫(kù)的需要
      • JWT 的這些特性使得我們可以完全依賴(lài)其無(wú)狀態(tài)的特性提供數(shù)據(jù) API 服務(wù),甚至是創(chuàng)建一個(gè)下載流服務(wù)。
      • 因?yàn)?JWT 并不使用 Cookie ,所以你可以使用任何域名提供你的 API 服務(wù)而不需要擔(dān)心跨域資源共享問(wèn)題(CORS)

    方式二:跨域的時(shí)候,可以把 JWT 放在 POST 請(qǐng)求的數(shù)據(jù)體里。

    方式三:通過(guò) URL 傳輸:http://www.example.com/user?token=xxx

    4.7 Token 和 JWT 的區(qū)別

    相同:

    • 都是訪問(wèn)資源的令牌
    • 都可以記錄用戶(hù)的信息
    • 都是使服務(wù)端無(wú)狀態(tài)化
    • 都是只有驗(yàn)證成功后,客戶(hù)端才能訪問(wèn)服務(wù)端上受保護(hù)的資源

    區(qū)別:

    • Token:服務(wù)端驗(yàn)證客戶(hù)端發(fā)送過(guò)來(lái)的 Token 時(shí),還需要查詢(xún)數(shù)據(jù)庫(kù)獲取用戶(hù)信息,然后驗(yàn)證 Token 是否有效。
    • JWT:將 Token 和 Payload 加密后存儲(chǔ)于客戶(hù)端,服務(wù)端只需要使用密鑰解密進(jìn)行校驗(yàn)(校驗(yàn)也是 JWT 自己實(shí)現(xiàn)的)即可,不需要查詢(xún)或者減少查詢(xún)數(shù)據(jù)庫(kù),因?yàn)?JWT 自包含了用戶(hù)信息和加密的數(shù)據(jù)。

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

  • Session-Cookie
  • Token 驗(yàn)證(包括 JWT,SSO)
  • OAuth2.0(開(kāi)放授權(quán))
  • 常見(jiàn)的加密算法

    • 哈希算法(Hash Algorithm)又稱(chēng)散列算法、散列函數(shù)、哈希函數(shù),是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。哈希算法將數(shù)據(jù)重新打亂混合,重新創(chuàng)建一個(gè)哈希值。
    • 哈希算法主要用來(lái)保障數(shù)據(jù)真實(shí)性(即完整性),即發(fā)信人將原始消息和哈希值一起發(fā)送,收信人通過(guò)相同的哈希函數(shù)來(lái)校驗(yàn)原始數(shù)據(jù)是否真實(shí)。
    • 哈希算法通常有以下幾個(gè)特點(diǎn):
      • 2 的 128 次方為 340282366920938463463374607431768211456,也就是 10 的 39 次方級(jí)別
      • 2 的 160 次方為 1.4615016373309029182036848327163e+48,也就是 10 的 48 次方級(jí)別
      • 2 的 256 次方為 1.1579208923731619542357098500869 × 10 的 77 次方,也就是 10 的 77 次方
      • 正像快速:原始數(shù)據(jù)可以快速計(jì)算出哈希值
      • 逆向困難:通過(guò)哈希值基本不可能推導(dǎo)出原始數(shù)據(jù)
      • 輸入敏感:原始數(shù)據(jù)只要有一點(diǎn)變動(dòng),得到的哈希值差別很大
      • 沖突避免:很難找到不同的原始數(shù)據(jù)得到相同的哈希值,宇宙中原子數(shù)大約在 10 的 60 次方到 80 次方之間,所以 2 的 256 次方有足夠的空間容納所有的可能,算法好的情況下沖突碰撞的概率很低:

    注意:

  • 以上不能保證數(shù)據(jù)被惡意篡改,原始數(shù)據(jù)和哈希值都可能被惡意篡改,要保證不被篡改,可以使用RSA 公鑰私鑰方案,再配合哈希值。
  • 哈希算法主要用來(lái)防止計(jì)算機(jī)傳輸過(guò)程中的錯(cuò)誤,早期計(jì)算機(jī)通過(guò)前 7 位數(shù)據(jù)第 8 位奇偶校驗(yàn)碼來(lái)保障(12.5% 的浪費(fèi)效率低),對(duì)于一段數(shù)據(jù)或文件,通過(guò)哈希算法生成 128bit 或者 256bit 的哈希值,如果校驗(yàn)有問(wèn)題就要求重傳。
  • 使用 cookie 時(shí)需要考慮的問(wèn)題

    • 因?yàn)榇鎯?chǔ)在客戶(hù)端,容易被客戶(hù)端篡改,使用前需要驗(yàn)證合法性
    • 不要存儲(chǔ)敏感數(shù)據(jù),比如用戶(hù)密碼,賬戶(hù)余額
    • 使用 httpOnly 在一定程度上提高安全性
    • 盡量減少 cookie 的體積,能存儲(chǔ)的數(shù)據(jù)量不能超過(guò) 4kb
    • 設(shè)置正確的 domain 和 path,減少數(shù)據(jù)傳輸
    • cookie 無(wú)法跨域
    • 一個(gè)瀏覽器針對(duì)一個(gè)網(wǎng)站最多存 20 個(gè)Cookie,瀏覽器一般只允許存放 300 個(gè)Cookie
    • 移動(dòng)端對(duì) cookie 的支持不是很好,而 session 需要基于 cookie 實(shí)現(xiàn),所以移動(dòng)端常用的是 token

    使用 session 時(shí)需要考慮的問(wèn)題

    • 將 session 存儲(chǔ)在服務(wù)器里面,當(dāng)用戶(hù)同時(shí)在線量比較多時(shí),這些 session 會(huì)占據(jù)較多的內(nèi)存,需要在服務(wù)端定期的去清理過(guò)期的 session
    • 當(dāng)網(wǎng)站采用集群部署的時(shí)候,會(huì)遇到多臺(tái) web 服務(wù)器之間如何做 session 共享的問(wèn)題。因?yàn)?session 是由單個(gè)服務(wù)器創(chuàng)建的,但是處理用戶(hù)請(qǐng)求的服務(wù)器不一定是那個(gè)創(chuàng)建 session 的服務(wù)器,那么該服務(wù)器就無(wú)法拿到之前已經(jīng)放入到 session 中的登錄憑證之類(lèi)的信息了。
    • 當(dāng)多個(gè)應(yīng)用要共享 session 時(shí),除了以上問(wèn)題,還會(huì)遇到跨域問(wèn)題,因?yàn)椴煌膽?yīng)用可能部署的主機(jī)不一樣,需要在各個(gè)應(yīng)用做好 cookie 跨域的處理。
    • sessionId 是存儲(chǔ)在 cookie 中的,假如瀏覽器禁止 cookie 或不支持 cookie 怎么辦? 一般會(huì)把 sessionId 跟在 url 參數(shù)后面即重寫(xiě) url,所以 session 不一定非得需要靠 cookie 實(shí)現(xiàn)
    • 移動(dòng)端對(duì) cookie 的支持不是很好,而 session 需要基于 cookie 實(shí)現(xiàn),所以移動(dòng)端常用的是 token

    使用 token 時(shí)需要考慮的問(wèn)題

    • 如果你認(rèn)為用數(shù)據(jù)庫(kù)來(lái)存儲(chǔ) token 會(huì)導(dǎo)致查詢(xún)時(shí)間太長(zhǎng),可以選擇放在內(nèi)存當(dāng)中。比如 redis 很適合你對(duì) token 查詢(xún)的需求。
    • token 完全由應(yīng)用管理,所以它可以避開(kāi)同源策略
    • token 可以避免 CSRF 攻擊(因?yàn)椴恍枰?cookie 了)
    • 移動(dòng)端對(duì) cookie 的支持不是很好,而 session 需要基于 cookie 實(shí)現(xiàn),所以移動(dòng)端常用的是 token

    使用 JWT 時(shí)需要考慮的問(wèn)題

    • 因?yàn)?JWT 并不依賴(lài) Cookie 的,所以你可以使用任何域名提供你的 API 服務(wù)而不需要擔(dān)心跨域資源共享問(wèn)題(CORS)
    • JWT 默認(rèn)是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次。
    • JWT 不加密的情況下,不能將秘密數(shù)據(jù)寫(xiě)入 JWT。
    • JWT 不僅可以用于認(rèn)證,也可以用于交換信息。有效使用 JWT,可以降低服務(wù)器查詢(xún)數(shù)據(jù)庫(kù)的次數(shù)。
    • JWT 最大的優(yōu)勢(shì)是服務(wù)器不再需要存儲(chǔ) Session,使得服務(wù)器認(rèn)證鑒權(quán)業(yè)務(wù)可以方便擴(kuò)展。但這也是 JWT 最大的缺點(diǎn):由于服務(wù)器不需要存儲(chǔ) Session 狀態(tài),因此使用過(guò)程中無(wú)法廢棄某個(gè) Token 或者更改 Token 的權(quán)限。也就是說(shuō)一旦 JWT 簽發(fā)了,到期之前就會(huì)始終有效,除非服務(wù)器部署額外的邏輯。
    • JWT 本身包含了認(rèn)證信息,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用,JWT的有效期應(yīng)該設(shè)置得比較短。對(duì)于一些比較重要的權(quán)限,使用時(shí)應(yīng)該再次對(duì)用戶(hù)進(jìn)行認(rèn)證。
    • JWT 適合一次性的命令認(rèn)證,頒發(fā)一個(gè)有效期極短的 JWT,即使暴露了危險(xiǎn)也很小,由于每次操作都會(huì)生成新的 JWT,因此也沒(méi)必要保存 JWT,真正實(shí)現(xiàn)無(wú)狀態(tài)。
    • 為了減少盜用,JWT 不應(yīng)該使用 HTTP 協(xié)議明碼傳輸,要使用 HTTPS 協(xié)議傳輸。

    使用加密算法時(shí)需要考慮的問(wèn)題

    • 絕不要以明文存儲(chǔ)密碼。
    • 永遠(yuǎn)使用 哈希算法 來(lái)處理密碼,絕不要使用 Base64 或其他編碼方式來(lái)存儲(chǔ)密碼,這和以明文存儲(chǔ)密碼是一樣的,使用哈希,而不要使用編碼。編碼以及加密,都是雙向的過(guò)程,而密碼是保密的,應(yīng)該只被它的所有者知道, 這個(gè)過(guò)程必須是單向的。哈希正是用于做這個(gè)的,從來(lái)沒(méi)有解哈希這種說(shuō)法, 但是編碼就存在解碼,加密就存在解密。
    • 絕不要使用弱哈希或已被破解的哈希算法,像 MD5 或 SHA1 ,只使用強(qiáng)密碼哈希算法。
    • 絕不要以明文形式顯示或發(fā)送密碼,即使是對(duì)密碼的所有者也應(yīng)該這樣。如果你需要 “忘記密碼” 的功能,可以隨機(jī)生成一個(gè)新的一次性的(這點(diǎn)很重要)密碼,然后把這個(gè)密碼發(fā)送給用戶(hù)。

    五、Session存儲(chǔ)方式與分布式解決方案

    5.1 session 復(fù)制

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

    • 優(yōu)點(diǎn): 可容錯(cuò),各個(gè)服務(wù)器間 session 能夠?qū)崟r(shí)響應(yīng)。
    • 缺點(diǎn): 會(huì)對(duì)網(wǎng)絡(luò)負(fù)荷造成一定壓力,如果 session 量大的話(huà)可能會(huì)造成網(wǎng)絡(luò)堵塞,拖慢服務(wù)器性能。

    5.2 粘性session /IP 綁定策略

    采用 Ngnix 中的 ip_hash 機(jī)制,將某個(gè) ip的所有請(qǐng)求都定向到同一臺(tái)服務(wù)器上,即將用戶(hù)與服務(wù)器綁定。 用戶(hù)第一次請(qǐng)求時(shí),負(fù)載均衡器將用戶(hù)的請(qǐng)求轉(zhuǎn)發(fā)到了 A 服務(wù)器上,如果負(fù)載均衡器設(shè)置了粘性 session 的話(huà),那么用戶(hù)以后的每次請(qǐng)求都會(huì)轉(zhuǎn)發(fā)到 A 服務(wù)器上,相當(dāng)于把用戶(hù)和 A 服務(wù)器粘到了一塊,這就是粘性 session 機(jī)制。

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

    5.3 session 共享(常用)

    • 使用分布式緩存方案比如 Memcached 、Redis 來(lái)緩存 session,但是要求 Memcached 或 Redis 必須是集群
    • 把 session 放到 Redis 中存儲(chǔ),雖然架構(gòu)上變得復(fù)雜,并且需要多訪問(wèn)一次 Redis ,但是這種方案帶來(lái)的好處也是很大的:
      • 實(shí)現(xiàn)了 session 共享;
      • 可以水平擴(kuò)展(增加 Redis 服務(wù)器);
      • 服務(wù)器重啟 session 不丟失(不過(guò)也要注意 session 在 Redis 中的刷新/失效機(jī)制);
      • 不僅可以跨服務(wù)器 session 共享,甚至可以跨平臺(tái)(例如網(wǎng)頁(yè)端和 APP 端)

    5.4 session 持久化

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

    • 優(yōu)點(diǎn): 服務(wù)器出現(xiàn)問(wèn)題,session 不會(huì)丟失。
    • 缺點(diǎn): 如果網(wǎng)站的訪問(wèn)量很大,把 session 存儲(chǔ)到數(shù)據(jù)庫(kù)中,會(huì)對(duì)數(shù)據(jù)庫(kù)造成很大壓力,還需要增加額外的開(kāi)銷(xiāo)維護(hù)數(shù)據(jù)庫(kù)。

    只要關(guān)閉瀏覽器 ,session 真的就消失了?不對(duì)。對(duì) session來(lái)說(shuō),除非程序通知服務(wù)器刪除一個(gè) session,否則服務(wù)器會(huì)一直保留,程序一般都是在用戶(hù)做 log off 的時(shí)候發(fā)個(gè)指令去刪除 session。然而瀏覽器從來(lái)不會(huì)主動(dòng)在關(guān)閉之前通知服務(wù)器它將要關(guān)閉,因此服務(wù)器根本不會(huì)有機(jī)會(huì)知道瀏覽器已經(jīng)關(guān)閉,之所以會(huì)有這種錯(cuò)覺(jué),是大部分 session 機(jī)制都使用會(huì)話(huà) cookie 來(lái)保存 session id,而關(guān)閉瀏覽器后這個(gè) session id 就消失了,再次連接服務(wù)器時(shí)也就無(wú)法找到原來(lái)的 session。如果服務(wù)器設(shè)置的 cookie 被保存在硬盤(pán)上,或者使用某種手段改寫(xiě)瀏覽器發(fā)出的 HTTP 請(qǐng)求頭,把原來(lái)的 session id 發(fā)送給服務(wù)器,則再次打開(kāi)瀏覽器仍然能夠打開(kāi)原來(lái)的 session。
    恰恰是由于關(guān)閉瀏覽器不會(huì)導(dǎo)致 session 被刪除,迫使服務(wù)器為 session 設(shè)置了一個(gè)失效時(shí)間,當(dāng)距離客戶(hù)端上一次使用 session 的時(shí)間超過(guò)這個(gè)失效時(shí)間時(shí),服務(wù)器就認(rèn)為客戶(hù)端已經(jīng)停止了活動(dòng),才會(huì)把 session 刪除以節(jié)省存儲(chǔ)空間。

    博文參考

    還分不清 Cookie、Session、Token、JWT? - 知乎

    總結(jié)

    以上是生活随笔為你收集整理的计算机网络——cookie、session、token原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。