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

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

生活随笔

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

编程问答

鉴权必须了解的5个知识点:cookie,session,token,jwt,单点登录

發(fā)布時(shí)間:2025/3/12 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 鉴权必须了解的5个知识点:cookie,session,token,jwt,单点登录 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從狀態(tài)說(shuō)起

[HTTP 無(wú)狀態(tài)]

我們知道,HTTP是無(wú)狀態(tài)的,也就是說(shuō),HTTP請(qǐng)求方和響應(yīng)方間無(wú)法維護(hù)狀態(tài),都是一次性的,它不知道前后的請(qǐng)求都發(fā)生了什么

但有的場(chǎng)景下,我們需要維護(hù)狀態(tài),最常見(jiàn)的,一個(gè)用戶(hù)登錄微博,發(fā)布,關(guān)注,評(píng)論,都是應(yīng)該在登錄后的用戶(hù)狀態(tài)下的

[標(biāo)記](méi)

在學(xué)?;蚬?#xff0c;入學(xué)入職那一天起,會(huì)錄入你的身份、賬戶(hù)信息,然后給你發(fā)個(gè)卡,今后在園區(qū)內(nèi),你的門(mén)禁、打卡、消費(fèi)都只需要刷這張卡

[前端存儲(chǔ)]

這就涉及一發(fā),一存,一帶,發(fā)好辦,登錄接口直接返回給前端,存儲(chǔ)就需要前端想辦法了,前提是,你要把卡帶在身上

前端的存儲(chǔ)方式有很多

  • 掛載到全局變量上,但這是個(gè)[體驗(yàn)卡],一次刷新頁(yè)面就沒(méi)了
  • 可以存到cookie,localStorage里,這屬于[會(huì)員卡],無(wú)論怎么刷新,只要瀏覽器沒(méi)清掉或者過(guò)期,就一直拿著這個(gè)狀態(tài)
基石:cookie

可是前端好麻煩啊,又要自己存,又要想辦法帶出去,有沒(méi)有不用操心的?

有,cookie

cookie也是前端存儲(chǔ)的一種,但相比于localStorage等其他方式,借助HTTP頭,瀏覽器能力,cookie可以做到前端無(wú)感知

一般過(guò)程是這樣的:

  • 在提供標(biāo)記的接口,通過(guò) HTTP 返回頭的 Set-Cookie 字段,直接「種」到瀏覽器上
  • 瀏覽器發(fā)起請(qǐng)求時(shí),會(huì)自動(dòng)把 cookie 通過(guò) HTTP 請(qǐng)求頭的 Cookie 字段,帶給接口
[配置:Domain / Path]

你不能拿清華的校園卡進(jìn)北大

cookie 是要限制:通過(guò)Domain(域) / Path(路徑)兩級(jí)(空間范圍)

Domain屬性指定瀏覽器發(fā)出 HTTP 請(qǐng)求時(shí),哪些域名要附帶這個(gè) Cookie。如果沒(méi)有指定該屬性,瀏覽器會(huì)默認(rèn)將其設(shè)為當(dāng)前 URL 的一級(jí)域名,比如 www.example.com 會(huì)設(shè)為 example.com,而且以后如果訪問(wèn)example.com的任何子域名,HTTP 請(qǐng)求也會(huì)帶上這個(gè) Cookie。如果服務(wù)器在Set-Cookie字段指定的域名,不屬于當(dāng)前域名,瀏覽器會(huì)拒絕這個(gè) Cookie。

Path屬性指定瀏覽器發(fā)出 HTTP 請(qǐng)求時(shí),哪些路徑要附帶這個(gè) Cookie。只要瀏覽器發(fā)現(xiàn),Path屬性是 HTTP 請(qǐng)求路徑的開(kāi)頭一部分,就會(huì)在頭信息里面帶上這個(gè) Cookie。比如,PATH屬性是/,那么請(qǐng)求/docs路徑也會(huì)包含該 Cookie。當(dāng)然,前提是域名必須一致

[配置:Expires / Max-Age]

你畢業(yè)了卡就不好使了

cookie 還可以限制 通過(guò)Expires,Max-Age中的一種 (時(shí)間范圍)

Expires屬性指定一個(gè)具體的到期時(shí)間,到了指定時(shí)間以后,瀏覽器就不再保留這個(gè) Cookie。它的值是 UTC 格式。如果不設(shè)置該屬性,或者設(shè)為null,Cookie 只在當(dāng)前會(huì)話(huà)(session)有效,瀏覽器窗口一旦關(guān)閉,當(dāng)前 Session 結(jié)束,該 Cookie 就會(huì)被刪除。另外,瀏覽器根據(jù)本地時(shí)間,決定 Cookie 是否過(guò)期,由于本地時(shí)間是不精確的,所以沒(méi)有辦法保證 Cookie 一定會(huì)在服務(wù)器指定的時(shí)間過(guò)期。

Max-Age屬性指定從現(xiàn)在開(kāi)始 Cookie 存在的秒數(shù),比如60 * 60 * 24 * 365(即一年)。過(guò)了這個(gè)時(shí)間以后,瀏覽器就不再保留這個(gè) Cookie。
如果同時(shí)指定了Expires和Max-Age,那么Max-Age的值將優(yōu)先生效。
如果Set-Cookie字段沒(méi)有指定Expires或Max-Age屬性,那么這個(gè) Cookie 就是 Session Cookie,即它只在本次對(duì)話(huà)存在,一旦用戶(hù)關(guān)閉瀏覽器,瀏覽器就不會(huì)再保留這個(gè) Cookie

[配置:Secure / HttpOnly]

有的學(xué)校規(guī)定,不帶卡套不讓刷(什么奇葩學(xué)校,假設(shè));有的學(xué)校不讓自己給卡貼貼紙。

Secure屬性指定瀏覽器只有在加密協(xié)議 HTTPS 下,才能將這個(gè) Cookie 發(fā)送到服務(wù)器。另一方面,如果當(dāng)前協(xié)議是 HTTP,瀏覽器會(huì)自動(dòng)忽略服務(wù)器發(fā)來(lái)的Secure屬性。該屬性只是一個(gè)開(kāi)關(guān),不需要指定值。如果通信是 HTTPS 協(xié)議,該開(kāi)關(guān)自動(dòng)打開(kāi)

HttpOnly屬性指定該 Cookie 無(wú)法通過(guò) JavaScript 腳本拿到,主要是Document.cookie屬性、XMLHttpRequest對(duì)象和 Request API 都拿不到該屬性。這樣就防止了該 Cookie 被腳本讀到,只有瀏覽器發(fā)出 HTTP 請(qǐng)求時(shí),才會(huì)帶上該 Cookie

[HTTP 頭對(duì)cookie的讀寫(xiě)]

HTTP 返回的一個(gè) Set-Cookie 頭用于向?yàn)g覽器寫(xiě)入「一條(且只能是一條)」cookie,格式為 cookie 鍵值 + 配置鍵值

Set-Cookie: username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly 1

那我想一次多 set 幾個(gè) cookie 怎么辦?多給幾個(gè) Set-Cookie 頭(一次 HTTP 請(qǐng)求中允許重復(fù))

[前端對(duì)cookie的讀寫(xiě)]

前端可以自己創(chuàng)建 cookie,如果服務(wù)端創(chuàng)建的 cookie 沒(méi)加HttpOnly,那恭喜你也可以修改他給的 cookie。

調(diào)用document.cookie可以創(chuàng)建、修改 cookie,和 HTTP 一樣,一次document.cookie能且只能操作一個(gè) cookie

document.cookie = 'username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly'; 1

調(diào)用document.cookie也可以讀到 cookie,也和 HTTP 一樣,能讀到所有的非HttpOnly cookie

console.log(document.cookie);// username=jimu; height=180; weight=80 1

那有了存儲(chǔ)工具,接下來(lái)怎么做呢?

應(yīng)用方案:服務(wù)端session

現(xiàn)在回想下,你刷卡的時(shí)候發(fā)生了什么?

其實(shí)你的卡上只存了一個(gè) id(可能是你的學(xué)號(hào)),刷的時(shí)候物業(yè)系統(tǒng)去查你的信息、賬戶(hù),再?zèng)Q定「這個(gè)門(mén)你能不能進(jìn)」「這個(gè)雞腿去哪個(gè)賬戶(hù)扣錢(qián)」

這種操作,在前后端鑒權(quán)系統(tǒng)中,叫 session

典型的 session 登陸/驗(yàn)證流程:

  • 瀏覽器登錄發(fā)送賬號(hào)密碼,服務(wù)端查用戶(hù)庫(kù),校驗(yàn)用戶(hù)
  • 服務(wù)端把用戶(hù)登錄狀態(tài)存為Session,生成一個(gè)sessionId
  • 通過(guò)登錄接口返回,把sessionId set到cookie上
  • 此后瀏覽器再請(qǐng)求業(yè)務(wù)接口,sessionId 隨cookie帶上
  • 服務(wù)端查sessionId校驗(yàn)session
  • 成功后正常做業(yè)務(wù)處理,返回結(jié)果
  • [Session 的存儲(chǔ)方式]

    服務(wù)端只是給 cookie 一個(gè) sessionId,而 session 的具體內(nèi)容(可能包含用戶(hù)信息、session 狀態(tài)等),要自己存一下。存儲(chǔ)的方式有幾種:

    Redis(推薦):內(nèi)存型數(shù)據(jù)庫(kù),redis中文官方網(wǎng)站。以 key-value 的形式存,正合 sessionId-sessionData 的場(chǎng)景;且訪問(wèn)快。
    內(nèi)存:直接放到變量里。一旦服務(wù)重啟就沒(méi)了
    數(shù)據(jù)庫(kù):普通數(shù)據(jù)庫(kù)。性能不高

    [Session 的過(guò)期和銷(xiāo)毀]

    很簡(jiǎn)單,只要把存儲(chǔ)的 session 數(shù)據(jù)銷(xiāo)毀就可以

    應(yīng)用方案:token

    我又想到學(xué)校,在沒(méi)有校園卡技術(shù)以前,我們都靠「學(xué)生證」。門(mén)衛(wèi)小哥直接對(duì)照我和學(xué)生證上的臉,確認(rèn)學(xué)生證有效期、年級(jí)等信息,就可以放行了

    回過(guò)頭來(lái)想想,一個(gè)登錄場(chǎng)景,也不必往 session 存太多東西,那為什么不直接打包到 cookie 中呢?這樣服務(wù)端不用存了,每次只要核驗(yàn) cookie 帶的「證件」有效性就可以了,也可以攜帶一些輕量的信息

    這種方式通常被叫做 token

    token的流程是這樣的:

  • 用戶(hù)登錄,服務(wù)端校驗(yàn)賬號(hào)密碼,獲取用戶(hù)信息
  • 把用戶(hù)信息,token配置編碼成token,通過(guò)cookie set到瀏覽器
  • 此后用戶(hù)請(qǐng)求業(yè)務(wù)接口,通過(guò)cookie攜帶token
  • 接口校驗(yàn)token有效性,進(jìn)行正常業(yè)務(wù)接口處理
  • session 和 token

    狹義上,我們通常認(rèn)為 session 是「種在 cookie 上、數(shù)據(jù)存在服務(wù)端」的認(rèn)證方案,token 是「客戶(hù)端存哪都行、數(shù)據(jù)存在 token 里」的認(rèn)證方案。對(duì) session 和 token 的對(duì)比本質(zhì)上是「客戶(hù)端存 cookie / 存別地兒」、「服務(wù)端存數(shù)據(jù) / 不存數(shù)據(jù)」的對(duì)比。

    單點(diǎn)登錄

    前面我們已經(jīng)知道了,在同域下的客戶(hù)端/服務(wù)端認(rèn)證系統(tǒng)中,通過(guò)客戶(hù)端攜帶憑證,維持一段時(shí)間內(nèi)的登錄狀態(tài)。

    但當(dāng)我們業(yè)務(wù)線(xiàn)越來(lái)越多,就會(huì)有更多業(yè)務(wù)系統(tǒng)分散到不同域名下,就需要「一次登錄,全線(xiàn)通用」的能力,叫做「單點(diǎn)登錄」

    虛假”的單點(diǎn)登錄(主域名相同)

    簡(jiǎn)單的,如果業(yè)務(wù)系統(tǒng)都在同一主域名下,比如wenku.baidu.com tieba.baidu.com,就好辦了??梢灾苯影?cookie domain 設(shè)置為主域名 baidu.com,百度也就是這么干的

    “真實(shí)”的單點(diǎn)登錄(主域名不同)

    比如滴滴這么潮的公司,同時(shí)擁有didichuxing.com xiaojukeji.com didiglobal.com等域名,種 cookie 是完全繞不開(kāi)的。

    這要能實(shí)現(xiàn)「一次登錄,全線(xiàn)通用」,才是真正的單點(diǎn)登錄。

    這種場(chǎng)景下,我們需要獨(dú)立的認(rèn)證服務(wù),通常被稱(chēng)為 SSO

  • 用戶(hù)進(jìn)入A系統(tǒng),沒(méi)有登錄憑證(ticket),A系統(tǒng)給他跳到SSO
  • SSO沒(méi)登錄過(guò),也就沒(méi)有sso系統(tǒng)下沒(méi)有憑證(注意這個(gè)和前面 A ticket是兩回事),輸入賬號(hào)密碼登錄
  • SSO賬號(hào)密碼驗(yàn)證成功,通過(guò)接口返回做兩件事,一是種下sso系統(tǒng)下憑證(記錄用戶(hù)登錄狀態(tài));二是下發(fā)一個(gè)ticket
  • 客戶(hù)端拿到ticket,保存起來(lái),帶著請(qǐng)求系統(tǒng)A接口
  • 系統(tǒng)A檢驗(yàn)ticket,成功后正常處理業(yè)務(wù)請(qǐng)求
  • 此時(shí)用戶(hù)第一次進(jìn)入系統(tǒng)B,沒(méi)有登錄憑證(ticket),B系統(tǒng)給他跳到SSO
  • SSO登錄過(guò),系統(tǒng)下有憑證,不用再次登錄,只需要下發(fā)ticket
  • 客戶(hù)端拿到ticket,保存起來(lái),帶著請(qǐng)求系統(tǒng)B接口
  • 總結(jié)

    • HTTP是無(wú)狀態(tài)的,為了維持前后請(qǐng)求,需要前端存儲(chǔ)標(biāo)記
    • cookie 是一種完善的標(biāo)記方式,通過(guò) HTTP 頭或 js 操作,有對(duì)應(yīng)的安全策略,是大多數(shù)狀態(tài)管理方案的基石
    • session 是一種狀態(tài)管理方案,前端通過(guò) cookie 存儲(chǔ) id,后端存儲(chǔ)數(shù)據(jù),但后端要處理分布式問(wèn)題
    • token 是另一種狀態(tài)管理方案,相比于 session 不需要后端存儲(chǔ),數(shù)據(jù)全部存在前端
    • token 的編碼技術(shù),通?;?base64,或增加加密算法防篡改,jwt 是一種成熟的編碼方案
    • session 和 token 的對(duì)比就是「用不用cookie」和「后端存不存」的對(duì)比
    • 單點(diǎn)登錄要求不同域下的系統(tǒng)「一次登錄,全線(xiàn)通用」,通常由獨(dú)立的 SSO 系統(tǒng)記錄登錄狀態(tài)、下發(fā) ticket,各業(yè)務(wù)系統(tǒng)配合存儲(chǔ)和認(rèn)證 ticket

    總結(jié)

    以上是生活随笔為你收集整理的鉴权必须了解的5个知识点:cookie,session,token,jwt,单点登录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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