名詞解釋
- session 會(huì)話腹侣,維護(hù)用戶狀態(tài)齿穗。會(huì)話中關(guān)聯(lián)了用戶信息。
- token 令牌跺株,用于簽權(quán)脖卖。
很多人糾結(jié)于token是什么,session又是什么畦木,但我認(rèn)為十籍,這就是兩個(gè)單詞唇礁,兩個(gè)概念而已娶吞,就看你怎么去實(shí)現(xiàn)并使用了械姻。
Session
session顧名思義就是會(huì)話,維護(hù)了用戶的狀態(tài)就是會(huì)話绣夺,這是為了解決http是stateless的問題發(fā)明的東西欢揖。
通常的用法是:
- 用戶使用賬號(hào)+密碼/手機(jī)號(hào)+驗(yàn)證碼登錄
- 后臺(tái)驗(yàn)證通過后會(huì)在Redis會(huì)話表里產(chǎn)生一條記錄,這條記錄就可以稱為會(huì)話她混!記錄里面有一個(gè)隨機(jī)的唯一值和用戶的信息坤按,這個(gè)隨機(jī)的唯一值會(huì)返回給客戶端保存,以后的接口通過這個(gè)唯一值進(jìn)行鑒權(quán)臭脓,這個(gè)唯一值可以稱為sessionId。
- 后臺(tái)接口帶上sessionId砚作,服務(wù)器拿到后去表里校驗(yàn)是否存在且有效嘹锁,有效則鑒權(quán)通過,無效則報(bào)錯(cuò)
Token
Token翻譯過來就是令牌米同,何為令牌瘤运,就是一個(gè)證明自己的證明。那拿剛才的sessionId來說拯坟,它又何常不是一個(gè)證明呢郁季?它證明了我之前是登錄過的钱磅,并且是有效的用戶似枕,所以我認(rèn)為,剛才的sessionId也可以稱為token凿歼,也有人認(rèn)為那就是token答憔。
看到這里估計(jì)又有人吐槽了,token的狀態(tài)是保存在客戶端的虐拓,session是服務(wù)端在管理狀態(tài)。這么理解的人是認(rèn)為城榛,session管理需要在后臺(tái)存表态兴,管理這個(gè)狀態(tài),而token后臺(tái)不需要保存工坊,因?yàn)閠oken里自帶了信息敢订,比如用戶基本信息、過期時(shí)間等昭齐,后臺(tái)每次收到直接解密校驗(yàn)即可矾柜,所以說token的狀態(tài)是保存在客戶端的。這么理解不是不可以里覆,很多人也是這么用的缆瓣,但有明確規(guī)定token就一定要帶信息嗎?別和我說JWT隧甚,JWT只是token的一種實(shí)現(xiàn)而已,不代表所有token都必須要有用戶信息忧便。我不反對(duì)有人這么理解帽借,因?yàn)閠oken和session本身就是概念,并不是規(guī)定切平,有不同的理解就可以有不同的實(shí)現(xiàn)辐董。
鑒權(quán)方案
剛其實(shí)已經(jīng)說到兩種實(shí)現(xiàn)了禀综,對(duì)于客戶端來講,拿到的就是一個(gè)字符串孤澎,并不關(guān)心它叫什么欠窒,也不關(guān)心服務(wù)端怎么去校驗(yàn)岖妄,只是每次請(qǐng)求里帶上這個(gè)字符串就好了。
服務(wù)端校驗(yàn)的兩種方式:
-
查表校驗(yàn)
這種方式就是session的通常用法了荐虐,服務(wù)端會(huì)建表福扬,把所有用戶的會(huì)話都存在Redis。這種方式是有好處的狠裹,可控度更高汽烦,要以隨時(shí)把一個(gè)發(fā)出去的token/sessionId置為失效,這是保障安全的一個(gè)重要手段碗暗。如何隨時(shí)失效呢?因?yàn)榭蛻舳嗣看握?qǐng)求帶的token/sessionId都需要去Redis里查找看是否存在且有效晴圾,無效就無法訪問了噪奄,是否有效由后臺(tái)決定勤篮,失效操作可以進(jìn)行邏輯刪除或物理刪除。
-
token自校驗(yàn)
這種方式就是用戶登錄后账劲,服務(wù)端把用戶信息和過期時(shí)間或一些其它信息進(jìn)行加密處理金抡,生成一個(gè)token返回給客戶端,客戶端下次帶token上來時(shí)榛瓮,服務(wù)端不需要去查表禀晓,因?yàn)檫@個(gè)token是帶用戶信息的坝锰,先對(duì)token進(jìn)行解密什黑,能解密出用戶信息說明這個(gè)token是服務(wù)端簽發(fā)的,再判斷是否過期拣凹,如果沒過期就有效恨豁。
此方案好處是不需要查表了嚣镜,省去了后臺(tái)session管理的一堆邏輯菊匿。也不需要考慮會(huì)話集群同步問題。但缺陷是這種token只能等它自動(dòng)失效徽职,無法由后臺(tái)決定是否失效佩厚。當(dāng)token被竊取進(jìn)行惡意攻擊時(shí)并沒有很好的對(duì)策抄瓦,看到這里就有人說了,定一個(gè)黑名單機(jī)制不就好了毯辅,如果定一個(gè)黑名單機(jī)制思恐,不也一樣要查表嗎立镶?那對(duì)比查表校驗(yàn)的優(yōu)勢(shì)又在哪呢媚媒?也會(huì)有人說把token的有效期設(shè)置短點(diǎn)不就安全了涩僻,但設(shè)置短了讓用戶頻繁登錄這種體驗(yàn)就很差了。
API安全設(shè)計(jì)
API的安全需要做好防竊取嵌巷、防篡改室抽、防重放等坪圾,安全都是相對(duì)的晓折,要在安全和效率做權(quán)衡。所以有效且安全的方案是Https + token + url簽名兽泄。
- https用來保證鏈路的安全病梢,避免數(shù)據(jù)被截取
- token是用來簽權(quán)的,看是否是合法的用戶
- url簽名是把請(qǐng)求參數(shù)做一個(gè)不可逆的算法簽名觅彰,作用一是保證內(nèi)容沒有被篡改填抬,作用二是也保證了客戶端的合法性痴奏,因?yàn)樗惴ㄊ呛秃笈_(tái)約定的
有些公司會(huì)使用時(shí)間戳校驗(yàn)读拆,如果時(shí)間相差超過一定時(shí)間就認(rèn)為無效,這種做法還有待商榷暑诸,因?yàn)橛锌赡苡脩舻臅r(shí)間是手動(dòng)調(diào)過的个榕,就不能以用戶手機(jī)的時(shí)間為準(zhǔn)了西采,如果用服務(wù)器時(shí)間就需要經(jīng)常請(qǐng)求继控,也不合適,那就需要一套用戶和服務(wù)器時(shí)間同步機(jī)制了霹崎,個(gè)人認(rèn)為不是很必要尾菇。
總結(jié)
token自校驗(yàn)這種方式更適用于開放平臺(tái)派诬,類似微信這種千埃,在token中加入信息去校驗(yàn)調(diào)用者是否符合要求放可,同時(shí)權(quán)限范圍也在token中有指定耀里。
查表校驗(yàn)更適用于自家App冯挎,有token/sessionId就可以執(zhí)行此用戶的所有操作房官。