所用技術(shù):
前端:Vue(2.x)、Vuex、Vue-Router、Nginx、node.js
后端:jsp
其實(shí)我也不想糾結(jié)這個(gè)問(wèn)題,但是業(yè)務(wù)逼著我糾結(jié)這個(gè)問(wèn)題?。ɑ蛟S很多人甚至不認(rèn)為這是一個(gè)問(wèn)題!你們覺(jué)得呢?)也可能因?yàn)槲揖褪且粋€(gè)糾結(jié)的人,但是我希望項(xiàng)目體驗(yàn)最好~~~
下面我列出了三種方案:
1.方案一:cookie(不設(shè)置過(guò)期時(shí)間)
個(gè)人不太喜歡這種方案,因?yàn)楹芏鄷r(shí)候,我打開(kāi)一個(gè)站點(diǎn),登陸,復(fù)制url,然后關(guān)閉瀏覽器,粘貼url,還是能夠訪問(wèn)的(不需要重新登陸),說(shuō)明這些站點(diǎn)并未采用這種存儲(chǔ)方式。歡迎補(bǔ)充你們的想法~~~
2.方案二:cookie(設(shè)置過(guò)期時(shí)間)
優(yōu)點(diǎn):過(guò)期瀏覽器自動(dòng)刪除
缺點(diǎn):需要人為維護(hù)過(guò)期時(shí)間
缺點(diǎn)解決方案:如果用戶在一定時(shí)間未使用系統(tǒng)(未交互),我們可以理解為,一定時(shí)間內(nèi)用戶沒(méi)有向服務(wù)器發(fā)送請(qǐng)求,我們可以在axios攔截里面修改cookie的過(guò)期時(shí)間。
3.方案三:localStorage
重點(diǎn)是第三種方案,這也是項(xiàng)目目前采用的方式,但是因?yàn)闃I(yè)務(wù)導(dǎo)致我糾結(jié)了。
項(xiàng)目相關(guān)背景:
本地存儲(chǔ)方式:localStorage
數(shù)據(jù)訪問(wèn):axios,采用攔截器方式,如果api返回的代碼為未登錄,元素js跳轉(zhuǎn)至登陸頁(yè)面
業(yè)務(wù)需求:
用戶登錄成功(localStorage存儲(chǔ)登錄信息)——》判斷是否設(shè)置支付密碼(localStorage存儲(chǔ)是否設(shè)置支付密碼)——》如果已設(shè)置,跳轉(zhuǎn)到主頁(yè);未設(shè)置,跳轉(zhuǎn)到設(shè)置頁(yè)。
成功跳轉(zhuǎn)至主頁(yè)(包含很多子頁(yè)——子路由),基本每個(gè)子路由頁(yè)面都會(huì)在進(jìn)入后調(diào)用一些查詢api,api攔截器里面返回如果未登錄,再跳轉(zhuǎn)至未登錄。
需求就是這么簡(jiǎn)單,但是問(wèn)題來(lái)了——有兩種情況下顯得問(wèn)題比較“嚴(yán)重”
1、假設(shè)登錄成功——》查詢到未設(shè)置支付密碼——》然后關(guān)閉瀏覽器,三天過(guò)后輸入登錄地址,因?yàn)閘ocalStorage未清空(也不能想cookie一樣過(guò)期),所以會(huì)跳轉(zhuǎn)到設(shè)置支付密碼頁(yè)面,因?yàn)檫@個(gè)頁(yè)面不需要調(diào)用查詢api,所以不會(huì)跳轉(zhuǎn)至登錄頁(yè),這個(gè)時(shí)候用戶會(huì)輸入“支付密碼”,點(diǎn)擊提交,然后會(huì)提示“用戶未登錄”,這樣體驗(yàn)就不好了——用戶的操作被浪費(fèi)了……
2、三天過(guò)后,首頁(yè)(包含登陸按鈕)——》點(diǎn)擊登陸,會(huì)自動(dòng)跳到“設(shè)置支付密碼”頁(yè)面(注意,不是登錄頁(yè)哦),因?yàn)槭且训卿洜顟B(tài),用戶設(shè)置支付密碼保存——》又跳轉(zhuǎn)到“登陸頁(yè)”,這種情況太嚴(yán)重了,已客戶的角度簡(jiǎn)直不可理解!
于是,我想到了cookie+設(shè)置過(guò)期時(shí)間的方式來(lái)處理,但是也有一些比較麻煩的事情;
那么,對(duì)于這種需求該如何進(jìn)行本地存儲(chǔ)才是最佳方案呢?
登錄信息存在 cookie 中是一直以來(lái)的做法,而且實(shí)現(xiàn)的很好,不用考慮各種問(wèn)題。
而 localStorage 是在這個(gè) API 誕生之后,一些 JS 黨帶起來(lái)的另一種實(shí)現(xiàn)方式。
使用 localStorage,你需要在每次請(qǐng)求的時(shí)候,都手動(dòng)帶上這個(gè)信息,這大大增加了開(kāi)發(fā)過(guò)程中帶來(lái)的困難,非常麻煩,而且還要手動(dòng)維護(hù)過(guò)期時(shí)間。
而使用 cookie 的話,只需要在后端的 Auth 模塊放個(gè)設(shè)置 header 的代碼即可,其他完全不用考慮。為什么:
Auth 模塊:
if (POST 方法請(qǐng)求登錄) {
if (賬號(hào)密碼不正確) {
return 重定向到登錄頁(yè)面,并提示錯(cuò)誤
}
設(shè)置 cookie,并指定過(guò)期時(shí)間為當(dāng)前時(shí)間 +n 天
return Auth 模塊邏輯結(jié)束,進(jìn)入其他模塊邏輯
}
if (沒(méi)有 cookie) {
return 重定向到登錄頁(yè)面
}
if (cookie 無(wú)效) {
// 可選步驟:設(shè)置 cookie 過(guò)期時(shí)間為 -1 (刪除 cookie)
return 重定向到登錄頁(yè)面
}
// 帶了有效的 cookie
設(shè)置 cookie 過(guò)期時(shí)間為當(dāng)前時(shí)間 +n 天(為 cookie 續(xù)期)
return Auth 模塊邏輯結(jié)束,進(jìn)入其他模塊邏輯
注意:只有請(qǐng)求 Auth 模塊才會(huì)給 cookie 續(xù)期,其他模塊不續(xù)。所以權(quán)限認(rèn)證的模塊都統(tǒng)一到一起了。
前端 js 什么都不用管,后端其他模塊也什么都不用管。
登錄/設(shè)置密碼:這是兩個(gè)模塊,不能搞混概念!然后有一個(gè)權(quán)限管理模塊(Auth)來(lái)管理。
首先,必須要用戶登錄才能操作,這里不管你把登錄信息存儲(chǔ)到哪里。
登錄成功后,有兩種選擇:
可以看出來(lái),首頁(yè)中判斷是否設(shè)置了密碼是必須的,而登錄頁(yè)不是。
那么,將判斷代碼放在首頁(yè),登錄成功后進(jìn)入首頁(yè),首頁(yè)判斷沒(méi)有設(shè)置密碼再跳到設(shè)置頁(yè),設(shè)置成功后,再跳轉(zhuǎn)到首頁(yè)。這個(gè)邏輯沒(méi)有問(wèn)題,也不會(huì)出現(xiàn)重復(fù)登錄的問(wèn)題。
首頁(yè):
if (未登錄) {
return 跳轉(zhuǎn)到登錄頁(yè);
}
if (未設(shè)置密碼) {
return 跳轉(zhuǎn)到設(shè)置密碼頁(yè);
}
// 已成功登錄并設(shè)置密碼,顯示頁(yè)面。
---------------------------------
登錄頁(yè):
if (已登錄) { // 防止用戶將登錄頁(yè)加入書(shū)簽,或者由于某些原因在已登錄的情況下進(jìn)入登錄頁(yè)
return 跳轉(zhuǎn)到首頁(yè);
}
// 未登錄,顯示登錄頁(yè)
登錄成功后直接跳回首頁(yè)。
---------------------------------
設(shè)置密碼頁(yè):
if (已設(shè)置密碼) {
顯示修改密碼頁(yè)
} else {
顯示設(shè)置密碼頁(yè)
}
設(shè)置成功后直接跳回首頁(yè)。
我不知道樓主設(shè)置密碼后為什么會(huì)跳轉(zhuǎn)到登錄頁(yè)面?既然已經(jīng)登錄了,在設(shè)置密碼后應(yīng)該直接跳回首頁(yè)?。窟@應(yīng)該是其他方面的邏輯問(wèn)題,而不是登錄信息存儲(chǔ)方式的問(wèn)題吧?
注:上面的 ***Storage 包括了 localStorage 和 sessionStorage。
還有其他的比如 web SQL、IndexedDB 兩個(gè)數(shù)據(jù)庫(kù),這一般是用來(lái)做 HTML 5 應(yīng)用的時(shí)候才會(huì)用到的。比如 PWA 或是 HTML5 頁(yè)游之類的。(貪玩藍(lán)月跟這沒(méi)關(guān)系(╯‵□′)╯︵┻━┻)
因?yàn)椋呵岸说囊磺卸际强梢允指牡陌。?br>不管是 cookie、localStorage 還是 sessionStorage,只要用戶按下 F12,分分鐘手改??!
這個(gè)網(wǎng)站要登錄?打開(kāi) F12,輸入 document.cookie='isLoggedIn=true'; 或者 localStorage.setItem('loggedIn', 'true');,你就,登錄成功???喵喵喵?
要設(shè)置密碼?同樣打開(kāi) F12 設(shè)置點(diǎn)東西。
這些判斷放在前端是完全沒(méi)有意義的啊喂!因?yàn)槟悴还芮岸伺袛嗖慌袛?,都要過(guò)一遍后端判斷才行啊?。?!
充分利用前端,也不能濫用啊喂!??!(╯‵□′)╯︵┻━┻
P.S. 當(dāng)然,這里我就不提 CSP 之類的網(wǎng)站安全規(guī)則了。。。又扯遠(yuǎn)了。。。
你的需求可以拆成兩個(gè)部分:認(rèn)證 和 鑒權(quán)
認(rèn)證識(shí)別這個(gè)用戶的身份
鑒權(quán)確定這個(gè)用戶訪問(wèn)首頁(yè)之后是否需要跳轉(zhuǎn)到綁定支付頁(yè)面
cookie 天生就是最適合做認(rèn)證,除了你提出的能否設(shè)置過(guò)期時(shí)間上的區(qū)別, cookie 和 localStorage 最大的區(qū)別是:每次 request 都會(huì)自動(dòng)在 header 中帶上所有的 cookie。所以如果你為了鑒權(quán),設(shè)置很多 cookie ,還會(huì)引發(fā)一個(gè)問(wèn)題就是,每次 request 的包都會(huì)很大。
我的解決方案很簡(jiǎn)單:鑒權(quán)就應(yīng)該交給后端去做。無(wú)論你多么細(xì)心的在 client 中維護(hù)用戶權(quán)限標(biāo)識(shí),都需要確保一點(diǎn):用戶的真實(shí)權(quán)限是否保持同步?所以你還是需要向后端查詢用戶權(quán)限設(shè)置,干嘛不簡(jiǎn)單些:
用戶認(rèn)證之后,后端鑒權(quán),提示是否跳轉(zhuǎn),或者干脆在 header 頭中設(shè)置跳轉(zhuǎn)鏈接。
你要先分清客戶端與服務(wù)端對(duì)“是否已登錄”的判斷是否一致? 如果不一致,就肯定會(huì)出現(xiàn) “訪問(wèn)頁(yè)面時(shí)是已登錄,但提交請(qǐng)求到服務(wù)器又返回未登錄”的情況。
如果這兩者對(duì)“是否登錄”的判斷是一致的,那無(wú)論你是用cookie,localstore,甚至是其它你任何能想到的辦法都不會(huì)有問(wèn)題。
你說(shuō)的情況,登錄成功后關(guān)掉瀏覽器三天后再訪問(wèn)登錄頁(yè)顯示已登錄,而提交設(shè)置支付密碼時(shí)服務(wù)端又提示未登錄,實(shí)際上就是服務(wù)端的與客戶端對(duì)登錄是否有效的判斷不一致,像這種情況, 你又不想提交業(yè)務(wù)請(qǐng)求后再返回未登錄
簡(jiǎn)單的做法,就是打開(kāi)任一頁(yè)面之前(比如vue的路由before),先判斷token是否有效(簡(jiǎn)單的判斷就是服務(wù)端生成token時(shí)增加過(guò)期時(shí)間加到token中,如果要確保登錄態(tài)一致,那就向服務(wù)端查詢),無(wú)效就是未登錄,跳到登錄頁(yè)。
建議登陸信息用 cookie。即設(shè)置過(guò)期時(shí)間的cookie ,看法是 cookie 默認(rèn)會(huì)發(fā)送回到后端,這樣方便后端讀取, 而localStorage的話必須你自己實(shí)現(xiàn)傳送到后端(一般由前端js實(shí)現(xiàn))。
另外, cookie有時(shí)效,而localStorage如果不手動(dòng)清理則永久保存。
如果要設(shè)置關(guān)閉網(wǎng)頁(yè)/標(biāo)簽就失效, 請(qǐng)用SessionStorage。 這個(gè)類似你設(shè)置“不帶時(shí)間的cookie”。
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。