Token登錄認(rèn)證

參考文章:

Token 認(rèn)證的來(lái)龍去脈

前后端分離使用 Token 登錄解決方案

理解Cookie和Session機(jī)制

基于 Cookie/Session 的認(rèn)證方案

Cookie

  • Cookie的工作原理

由于HTTP是一種無(wú)狀態(tài)的協(xié)議颅悉,服務(wù)器單從網(wǎng)絡(luò)連接上無(wú)從知道客戶身份。怎么辦呢迁匠?就給客戶端們頒發(fā)一個(gè)通行證吧剩瓶,每人一個(gè),無(wú)論誰(shuí)訪問(wèn)都必須攜帶自己通行證城丧。這樣服務(wù)器就能從通行證上確認(rèn)客戶身份了延曙。這就是。
cookie指的就是在瀏覽器里面存儲(chǔ)的一種數(shù)據(jù)芙贫,僅僅是瀏覽器實(shí)現(xiàn)的一種數(shù)據(jù)存儲(chǔ)功能搂鲫。
cookie的保存時(shí)間,可以自己在程序中設(shè)置磺平。如果沒(méi)有設(shè)置保存時(shí)間魂仍,應(yīng)該是一關(guān)閉瀏覽器拐辽,cookie就自動(dòng)消失。

Cookie實(shí)際上是一小段的文本信息擦酌【阒睿客戶端請(qǐng)求服務(wù)器,如果服務(wù)器需要記錄該用戶狀態(tài)赊舶,就使用response向客戶端瀏覽器頒發(fā)一個(gè)Cookie睁搭。客戶端瀏覽器會(huì)把Cookie保存起來(lái)笼平。當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí)园骆,瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器。服務(wù)器檢查該Cookie寓调,以此來(lái)辨認(rèn)用戶狀態(tài)锌唾。服務(wù)器還可以根據(jù)需要修改Cookie的內(nèi)容。

注意Cookie功能需要瀏覽器的支持夺英。如果瀏覽器不支持Cookie(如大部分手機(jī)中的瀏覽器)或者把Cookie禁用了晌涕,Cookie功能就會(huì)失效。不同的瀏覽器采用不同的方式保存Cookie痛悯。IE瀏覽器會(huì)以文本文件形式保存余黎,一個(gè)文本文件保存一個(gè)Cookie

  • Cookie的不可跨域名性

Cookie具有不可跨域名性载萌。根據(jù)Cookie規(guī)范惧财,瀏覽器訪問(wèn)Google只會(huì)攜帶GoogleCookie,而不會(huì)攜帶BaiduCookie炒考。瀏覽器判斷一個(gè)網(wǎng)站是否能操作另一個(gè)網(wǎng)站Cookie的依據(jù)是域名可缚。

Session

Session是另一種記錄客戶狀態(tài)的機(jī)制,不同的是Cookie保存在客戶端瀏覽器中斋枢,而Session保存在服務(wù)器上帘靡。客戶端瀏覽器訪問(wèn)服務(wù)器的時(shí)候瓤帚,服務(wù)器把客戶端信息以某種形式記錄在服務(wù)器上描姚。這就是Session「甏危客戶端瀏覽器再次訪問(wèn)時(shí)只需要從該Session中查找該客戶的狀態(tài)就可以了轩勘。

如果說(shuō)Cookie機(jī)制是通過(guò)檢查客戶身上的“通行證”來(lái)確定客戶身份的話,那么Session機(jī)制就是通過(guò)檢查服務(wù)器上的“客戶明細(xì)表”來(lái)確認(rèn)客戶身份怯邪。

session 也是類(lèi)似的道理绊寻,服務(wù)器要知道當(dāng)前發(fā)請(qǐng)求給自己的是誰(shuí)。為了做這種區(qū)分,服務(wù)器就要給每個(gè)客戶端分配不同的“身份標(biāo)識(shí)”澄步,然后客戶端每次向服務(wù)器發(fā)請(qǐng)求的時(shí)候冰蘑,都帶上這個(gè)“身份標(biāo)識(shí)”,服務(wù)器就知道這個(gè)請(qǐng)求來(lái)自于誰(shuí)了村缸。對(duì)于瀏覽器客戶端祠肥,大家都默認(rèn)采用 cookie 的方式,保存這個(gè)“身份標(biāo)識(shí)”梯皿。

服務(wù)器使用session把用戶的信息臨時(shí)保存在了服務(wù)器上仇箱,用戶離開(kāi)網(wǎng)站后session會(huì)被銷(xiāo)毀。這種用戶信息存儲(chǔ)方式相對(duì)cookie來(lái)說(shuō)更安东羹。

可是session有一個(gè)缺陷:如果web服務(wù)器做了負(fù)載均衡剂桥,那么下一個(gè)操作請(qǐng)求到了另一臺(tái)服務(wù)器的時(shí)候session會(huì)丟失。

提示Session的使用比Cookie方便属提,但是過(guò)多的Session存儲(chǔ)在服務(wù)器內(nèi)存中渊额,會(huì)對(duì)服務(wù)器造成壓力。

Cookie與Session的區(qū)別和聯(lián)系

  1. cookie數(shù)據(jù)存放在客戶的瀏覽器上垒拢,session數(shù)據(jù)放在服務(wù)器上;

  2. cookie不是很安全火惊,別人可以分析存放在本地的COOKIE并進(jìn)行 COOKIE欺騙求类,考慮到安全應(yīng)當(dāng)使用session

  3. session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上屹耐。當(dāng)訪問(wèn)增多尸疆,會(huì)比較占用你服務(wù)器的性能』塘耄考慮到減輕服務(wù)器性能方面寿弱,應(yīng)當(dāng)使用COOKIE

  4. 單個(gè)cookie在客戶端的限制是3K按灶,就是說(shuō)一個(gè)站點(diǎn)在客戶端存放的COOKIE不能超過(guò)3K症革;

CookieSession的方案雖然分別屬于客戶端和服務(wù)端,但是服務(wù)端的session的實(shí)現(xiàn)對(duì)客戶端的cookie有依賴關(guān)系的鸯旁,上面我講到服務(wù)端執(zhí)行session機(jī)制時(shí)候會(huì)生成session的id值噪矛,這個(gè)id值會(huì)發(fā)送給客戶端,客戶端每次請(qǐng)求都會(huì)把這個(gè)id值放到http請(qǐng)求的頭部發(fā)送給服務(wù)端铺罢,而這個(gè)id值在客戶端會(huì)保存下來(lái)艇挨,保存的容器就是cookie,因此當(dāng)我們完全禁掉瀏覽器的cookie的時(shí)候韭赘,服務(wù)端的session也會(huì)不能正常使用缩滨。

基于token的認(rèn)證方式

在大多數(shù)使用Web API的互聯(lián)網(wǎng)公司中,tokens 是多用戶下處理認(rèn)證的最佳方式。

以下幾點(diǎn)特性會(huì)讓你在程序中使用基于Token的身份驗(yàn)證

1.無(wú)狀態(tài)脉漏、可擴(kuò)展

2.支持移動(dòng)設(shè)備

3.跨程序調(diào)用

4.安全

Token的起源

在介紹基于Token的身份驗(yàn)證的原理與優(yōu)勢(shì)之前苞冯,不妨先看看之前的認(rèn)證都是怎么做的。

  • 基于服務(wù)器的驗(yàn)證

我們都是知道HTTP協(xié)議是無(wú)狀態(tài)的鸠删,這種無(wú)狀態(tài)意味著程序需要驗(yàn)證每一次請(qǐng)求抱完,從而辨別客戶端的身份。

在這之前刃泡,程序都是通過(guò)在服務(wù)端存儲(chǔ)的登錄信息來(lái)辨別請(qǐng)求的巧娱。這種方式一般都是通過(guò)存儲(chǔ)Session來(lái)完成。

  • 基于服務(wù)器驗(yàn)證方式暴露的一些問(wèn)題

1.Seesion:每次認(rèn)證用戶發(fā)起請(qǐng)求時(shí)烘贴,服務(wù)器需要去創(chuàng)建一個(gè)記錄來(lái)存儲(chǔ)信息禁添。當(dāng)越來(lái)越多的用戶發(fā)請(qǐng)求時(shí),內(nèi)存的開(kāi)銷(xiāo)也會(huì)不斷增加桨踪。

2.可擴(kuò)展性:在服務(wù)端的內(nèi)存中使用Seesion存儲(chǔ)登錄信息老翘,伴隨而來(lái)的是可擴(kuò)展性問(wèn)題。

3.CORS(跨域資源共享):當(dāng)我們需要讓數(shù)據(jù)跨多臺(tái)移動(dòng)設(shè)備上使用時(shí)锻离,跨域資源的共享會(huì)是一個(gè)讓人頭疼的問(wèn)題铺峭。在使用Ajax抓取另一個(gè)域的資源,就可以會(huì)出現(xiàn)禁止請(qǐng)求的情況汽纠。

4.CSRF(跨站請(qǐng)求偽造):用戶在訪問(wèn)銀行網(wǎng)站時(shí)卫键,他們很容易受到跨站請(qǐng)求偽造的攻擊,并且能夠被利用其訪問(wèn)其他的網(wǎng)站虱朵。

在這些問(wèn)題中莉炉,可擴(kuò)展行是最突出的。因此我們有必要去尋求一種更有行之有效的方法碴犬。

基于Token的驗(yàn)證原理

基于Token的身份驗(yàn)證是無(wú)狀態(tài)的絮宁,我們不將用戶信息存在服務(wù)器中。這種概念解決了在服務(wù)端存儲(chǔ)信息時(shí)的許多問(wèn)題服协。NoSession意味著你的程序可以根據(jù)需要去增減機(jī)器绍昂,而不用去擔(dān)心用戶是否登錄。

基于Token的身份驗(yàn)證的過(guò)程如下:

  1. 用戶通過(guò)用戶名和密碼發(fā)送請(qǐng)求偿荷。

  2. 服務(wù)器端程序驗(yàn)證治专。

3.服務(wù)器端程序返回一個(gè)帶簽名token 給客戶端。

4.客戶端儲(chǔ)存token,并且每次訪問(wèn)API都攜帶Token到服務(wù)器端的遭顶。

5.服務(wù)端驗(yàn)證token张峰,校驗(yàn)成功則返回請(qǐng)求數(shù)據(jù),校驗(yàn)失敗則返回錯(cuò)誤碼棒旗。

image

Tokens的優(yōu)勢(shì)

  • 無(wú)狀態(tài)喘批、可擴(kuò)展

在客戶端存儲(chǔ)的Tokens是無(wú)狀態(tài)的撩荣,并且能夠被擴(kuò)展∪纳睿基于這種無(wú)狀態(tài)和不存儲(chǔ)Session信息餐曹,負(fù)載負(fù)載均衡器能夠?qū)⒂脩粜畔囊粋€(gè)服務(wù)傳到其他服務(wù)器上。
tokens自己hold住了用戶的驗(yàn)證信息敌厘。

  • 安全性

請(qǐng)求中發(fā)送token而不再是發(fā)送cookie能夠防止CSRF(跨站請(qǐng)求偽造)台猴。即使在客戶端使用cookie存儲(chǔ)tokencookie也僅僅是一個(gè)存儲(chǔ)機(jī)制而不是用于認(rèn)證俱两。不將信息存儲(chǔ)在Session中饱狂,讓我們少了對(duì)session操作。

token是有時(shí)效的宪彩,一段時(shí)間之后用戶需要重新驗(yàn)證休讳。

  • 可擴(kuò)展性

Tokens能夠創(chuàng)建與其它程序共享權(quán)限的程序。

  • 多平臺(tái)跨域

我們提前先來(lái)談?wù)撘幌?code>CORS(跨域資源共享)尿孔,對(duì)應(yīng)用程序和服務(wù)進(jìn)行擴(kuò)展的時(shí)候俊柔,需要介入各種各種的設(shè)備和應(yīng)用程序。

需要設(shè)置有效期嗎活合?

對(duì)于這個(gè)問(wèn)題雏婶,我們不妨先看兩個(gè)例子。一個(gè)例子是登錄密碼白指,一般要求定期改變密碼尚骄,以防止泄漏,所以密碼是有有效期的侵续;另一個(gè)例子是安全證書(shū)。SSL 安全證書(shū)都有有效期憨闰,目的是為了解決吊銷(xiāo)的問(wèn)題状蜗。所以無(wú)論是從安全的角度考慮,還是從吊銷(xiāo)的角度考慮鹉动,Token 都需要設(shè)有效期轧坎。

  • 那么有效期多長(zhǎng)合適呢?

只能說(shuō)泽示,根據(jù)系統(tǒng)的安全需要缸血,盡可能的短,但也不能短得離譜

  • 然后新問(wèn)題產(chǎn)生了械筛,如果用戶在正常操作的過(guò)程中捎泻,Token 過(guò)期失效了,要求用戶重新登錄……用戶體驗(yàn)豈不是很糟糕埋哟?

一種方案笆豁,使用 Refresh Token,它可以避免頻繁的讀寫(xiě)操作。這種方案中闯狱,服務(wù)端不需要刷新 Token 的過(guò)期時(shí)間煞赢,一旦 Token 過(guò)期,就反饋給前端哄孤,前端使用 Refresh Token 申請(qǐng)一個(gè)全新Token 繼續(xù)使用照筑。這種方案中,服務(wù)端只需要在客戶端請(qǐng)求更新 Token 的時(shí)候?qū)?Refresh Token 的有效性進(jìn)行一次檢查瘦陈,大大減少了更新有效期的操作凝危,也就避免了頻繁讀寫(xiě)。當(dāng)然 Refresh Token 也是有有效期的双饥,但是這個(gè)有效期就可以長(zhǎng)一點(diǎn)了媒抠,比如,以天為單位的時(shí)間咏花。

  • 時(shí)序圖表示

使用 TokenRefresh Token 的時(shí)序圖如下:

1)登錄

image

2)業(yè)務(wù)請(qǐng)求

image

3)Token過(guò)期趴生,刷新 Token

image

上面的時(shí)序圖中并未提到 Refresh Token 過(guò)期怎么辦。不過(guò)很顯然昏翰,Refresh Token 既然已經(jīng)過(guò)期苍匆,就該要求用戶重新登錄了。

項(xiàng)目中使用token總結(jié)

使用基于 Token 的身份驗(yàn)證方法棚菊,在服務(wù)端不需要存儲(chǔ)用戶的登錄記錄浸踩。大概的流程是這樣的:

1.前端使用用戶名跟密碼請(qǐng)求首次登錄

2.后服務(wù)端收到請(qǐng)求,去驗(yàn)證用戶名與密碼是否正確

3.驗(yàn)證成功后统求,服務(wù)端會(huì)根據(jù)用戶id检碗、用戶名、定義好的秘鑰码邻、過(guò)期時(shí)間生成一個(gè) Token折剃,再把這個(gè) Token 發(fā)送給前端

4.前端收到 返回的Token ,把它存儲(chǔ)起來(lái)像屋,比如放在 Cookie 里或者 Local Storage

export interface User {
    token: string;
    userInfo: UserInfo | any;
    companyInfo: CompanyInfo | any;
    resources?: string[];
}
save(key: string, value: any, storageType ?: StorageType) {
    return this.storageService.put(
        {
            pool: key,
            key: 'chris-app',
            storageType: StorageType.localStorage
        },
        value
    );
}
this.storageService.save(CACHE_USER_KEY, user);

5.前端每次路由跳轉(zhuǎn)怕犁,判斷 localStroage 有無(wú) token ,沒(méi)有則跳轉(zhuǎn)到登錄頁(yè)己莺。有則請(qǐng)求獲取用戶信息奏甫,改變登錄狀態(tài);
6.前端每次向服務(wù)端請(qǐng)求資源的時(shí)候需要在請(qǐng)求頭里攜帶服務(wù)端簽發(fā)的Token

HttpInterceptor => headers = headers.set('token', this.authService.getToken());

7.服務(wù)端收到請(qǐng)求凌受,然后去驗(yàn)證前端請(qǐng)求里面帶著的 Token阵子。沒(méi)有或者 token 過(guò)期,返回401胜蛉。如果驗(yàn)證成功款筑,就向前端返回請(qǐng)求的數(shù)據(jù)智蝠。

8.前端得到 401 狀態(tài)碼,重定向到登錄頁(yè)面奈梳。

HttpInterceptor => 
    401: '用戶登陸狀態(tài)失效杈湾,請(qǐng)重新登陸。'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末攘须,一起剝皮案震驚了整個(gè)濱河市漆撞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌于宙,老刑警劉巖浮驳,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異捞魁,居然都是意外死亡至会,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)谱俭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奉件,“玉大人,你說(shuō)我怎么就攤上這事昆著∠孛玻” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵凑懂,是天一觀的道長(zhǎng)煤痕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)接谨,這世上最難降的妖魔是什么摆碉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮脓豪,結(jié)果婚禮上巷帝,老公的妹妹穿的比我還像新娘。我一直安慰自己跑揉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布埠巨。 她就那樣靜靜地躺著历谍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辣垒。 梳的紋絲不亂的頭發(fā)上望侈,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音勋桶,去河邊找鬼脱衙。 笑死侥猬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捐韩。 我是一名探鬼主播退唠,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荤胁!你這毒婦竟也來(lái)了瞧预?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤仅政,失蹤者是張志新(化名)和其女友劉穎垢油,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體圆丹,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滩愁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辫封。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硝枉。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秸讹,靈堂內(nèi)的尸體忽然破棺而出檀咙,到底是詐尸還是另有隱情,我是刑警寧澤璃诀,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布弧可,位于F島的核電站,受9級(jí)特大地震影響劣欢,放射性物質(zhì)發(fā)生泄漏棕诵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一凿将、第九天 我趴在偏房一處隱蔽的房頂上張望校套。 院中可真熱鬧,春花似錦牧抵、人聲如沸笛匙。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)妹孙。三九已至,卻和暖如春获枝,著一層夾襖步出監(jiān)牢的瞬間蠢正,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工省店, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嚣崭,地道東北人笨触。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像雹舀,于是被迫代替她去往敵國(guó)和親芦劣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容