在簡單理解cookie/session機(jī)制這篇文章中,簡要闡述了cookie和session的原理。本文將要簡單闡述另一個(gè)同cookie/session同樣重要的技術(shù)術(shù)語:token。
什么是token
token的意思是“令牌”,是服務(wù)端生成的一串字符串,作為客戶端進(jìn)行請(qǐng)求的一個(gè)標(biāo)識(shí)。
當(dāng)用戶第一次登錄后,服務(wù)器生成一個(gè)token并將此token返回給客戶端,以后客戶端只需帶上這個(gè)token前來請(qǐng)求數(shù)據(jù)即可,無需再次帶上用戶名和密碼。
簡單token的組成;uid(用戶唯一的身份標(biāo)識(shí))、time(當(dāng)前時(shí)間的時(shí)間戳)、sign(簽名,token的前幾位以哈希算法壓縮成的一定長度的十六進(jìn)制字符串。為防止token泄露)。
身份認(rèn)證概述
由于http是一種沒有狀態(tài)的協(xié)議,它并不知道是誰訪問了我們的應(yīng)用。這里把用戶看成是客戶端,客戶端使用用戶名還有密碼通過了身份驗(yàn)證,不過下次這個(gè)客戶端再發(fā)送請(qǐng)求時(shí)候,還得再驗(yàn)證一下。
通用的解決方法就是,當(dāng)用戶請(qǐng)求登錄的時(shí)候,如果沒有問題,在服務(wù)端生成一條記錄,在這個(gè)記錄里可以說明登錄的用戶是誰,然后把這條記錄的id發(fā)送給客戶端,客戶端收到以后把這個(gè)id存儲(chǔ)在cookie里,下次該用戶再次向服務(wù)端發(fā)送請(qǐng)求的時(shí)候,可以帶上這個(gè)cookie,這樣服務(wù)端會(huì)驗(yàn)證一下cookie里的信息,看能不能在服務(wù)端這里找到對(duì)應(yīng)的記錄,如果可以,說明用戶已經(jīng)通過了身份驗(yàn)證,就把用戶請(qǐng)求的數(shù)據(jù)返回給客戶端。
以上所描述的過程就是利用session,那個(gè)id值就是sessionid。我們需要在服務(wù)端存儲(chǔ)為用戶生成的session,這些session會(huì)存儲(chǔ)在內(nèi)存,磁盤,或者數(shù)據(jù)庫。
基于token機(jī)制的身份認(rèn)證
使用token機(jī)制的身份驗(yàn)證方法,在服務(wù)器端不需要存儲(chǔ)用戶的登錄記錄。大概的流程:
客戶端使用用戶名和密碼請(qǐng)求登錄。
服務(wù)端收到請(qǐng)求,驗(yàn)證用戶名和密碼。
驗(yàn)證成功后,服務(wù)端會(huì)生成一個(gè)token,然后把這個(gè)token發(fā)送給客戶端。
客戶端收到token后把它存儲(chǔ)起來,可以放在cookie或者local storage(本地存儲(chǔ))里。
客戶端每次向服務(wù)端發(fā)送請(qǐng)求的時(shí)候都需要帶上服務(wù)端發(fā)給的token。
服務(wù)端收到請(qǐng)求,然后去驗(yàn)證客戶端請(qǐng)求里面帶著token,如果驗(yàn)證成功,就向客戶端返回請(qǐng)求的數(shù)據(jù)。
利用token機(jī)制進(jìn)行登錄認(rèn)證,可以有以下方式:
a.用設(shè)備mac地址作為token
客戶端:客戶端在登錄時(shí)獲取設(shè)備的mac地址,將其作為參數(shù)傳遞到服務(wù)端
服務(wù)端:服務(wù)端接收到該參數(shù)后,便用一個(gè)變量來接收,同時(shí)將其作為token保存在數(shù)據(jù)庫,并將該token設(shè)置到session中。客戶端每次請(qǐng)求的時(shí)候都要統(tǒng)一攔截,將客戶端傳遞的token和服務(wù)器端session中的token進(jìn)行對(duì)比,相同則登錄成功,不同則拒絕。
此方式客戶端和服務(wù)端統(tǒng)一了唯一的標(biāo)識(shí),并且保證每一個(gè)設(shè)備擁有唯一的標(biāo)識(shí)。缺點(diǎn)是服務(wù)器端需要保存mac地址;優(yōu)點(diǎn)是客戶端無需重新登錄,只要登錄一次以后一直可以使用,對(duì)于超時(shí)的問題由服務(wù)端進(jìn)行處理。
b.用sessionid作為token
客戶端:客戶端攜帶用戶名和密碼登錄
服務(wù)端:接收到用戶名和密碼后進(jìn)行校驗(yàn),正確就將本地獲取的sessionid作為token返回給客戶端,客戶端以后只需帶上請(qǐng)求的數(shù)據(jù)即可。
此方式的優(yōu)點(diǎn)是方便,不用存儲(chǔ)數(shù)據(jù),缺點(diǎn)就是當(dāng)session過期時(shí),客戶端必須重新登錄才能請(qǐng)求數(shù)據(jù)。
當(dāng)然,對(duì)于一些保密性較高的應(yīng)用,可以采取兩種方式結(jié)合的方式,將設(shè)備mac地址與用戶名密碼同時(shí)作為token進(jìn)行認(rèn)證。
app利用token機(jī)制進(jìn)行身份認(rèn)證
用戶在登錄app時(shí),app端會(huì)發(fā)送加密的用戶名和密碼到服務(wù)器,服務(wù)器驗(yàn)證用戶名和密碼,如果驗(yàn)證成功,就會(huì)生成相應(yīng)位數(shù)的字符產(chǎn)作為token存儲(chǔ)到服務(wù)器中,并且將該token返回給app端。
以后app再次請(qǐng)求時(shí),凡是需要驗(yàn)證的地方都要帶上該token,然后服務(wù)器端驗(yàn)證token,成功返回所需要的結(jié)果,失敗返回錯(cuò)誤信息,讓用戶重新登錄。其中,服務(wù)器上會(huì)給token設(shè)置一個(gè)有效期,每次app請(qǐng)求的時(shí)候都驗(yàn)證token和有效期。
token的存儲(chǔ)
token可以存到數(shù)據(jù)庫中,但是有可能查詢token的時(shí)間會(huì)過長導(dǎo)致token丟失(其實(shí)token丟失了再重新認(rèn)證一個(gè)就好,但是別丟太頻繁,別讓用戶沒事兒就去認(rèn)證)。
為了避免查詢時(shí)間過長,可以將token放到內(nèi)存中。這樣查詢速度絕對(duì)就不是問題了,也不用太擔(dān)心占據(jù)內(nèi)存,就算token是一個(gè)32位的字符串,應(yīng)用的用戶量在百萬級(jí)或者千萬級(jí),也是占不了多少內(nèi)存的。
token的加密
token是很容易泄露的,如果不進(jìn)行加密處理,很容易被惡意拷貝并用來登錄。加密的方式一般有:
在存儲(chǔ)的時(shí)候把token進(jìn)行對(duì)稱加密存儲(chǔ),用到的時(shí)候再解密。
文章最開始提到的簽名sign:將請(qǐng)求url、時(shí)間戳、token三者合并,通過算法進(jìn)行加密處理。
最好是兩種方式結(jié)合使用。
還有一點(diǎn),在網(wǎng)絡(luò)層面上token使用明文傳輸?shù)脑捠欠浅NkU(xiǎn)的,所以一定要使用https協(xié)議。
總結(jié)
以上就是對(duì)于token在用戶身份認(rèn)證過程中的簡單總結(jié)。希望沒有技術(shù)背景的產(chǎn)品經(jīng)理們在和開發(fā)哥哥溝通的時(shí)候不要再被這些技術(shù)術(shù)語問住了。
作者:流年,互聯(lián)網(wǎng)產(chǎn)品設(shè)計(jì)師,4年互聯(lián)網(wǎng)產(chǎn)品設(shè)計(jì)經(jīng)驗(yàn)。
本文由 @流年 原創(chuàng)發(fā)布。未經(jīng)許可,禁止轉(zhuǎn)載。
題圖由作者提供
Linux防火墻-SELinux、netfilter、iptables、ifconfig衛(wèi)龍即將港股上市,域名卻...高校圖書館云服務(wù)器配置案例找不到降權(quán)原因怎么辦?試試這些方法phpmyadmin出現(xiàn)1862錯(cuò)誤怎么辦?“黑色星期五”在華遇冷 海淘屬性很難在短時(shí)間得到認(rèn)同終端應(yīng)用與與云服務(wù)器配置廣東云服務(wù)器的價(jià)格