最近處理 nuxt 同構應用的權限問題,用 cookie-universal-nuxt 來進行 cookie 操作,遇到一點惱人的問題,現(xiàn)記錄如下供參閱。
問題一:
服務端請求端口返回401權限錯誤
線索:
- 服務端請求時會自己帶上奇怪的token,此時 document.cookie 中并無token,這個奇怪的token哪來的?
- 觀察發(fā)生的時機,發(fā)現(xiàn) 401 在 QQ 第三方登陸后回跳網站后的 nuxtServerInit 中發(fā)生,此時 token 通過 $cookies.get('token') 取得
- 查看 cookie-universal 源碼發(fā)現(xiàn)服務端的 cookie 是通過 req.headers.cookie 獲得的
- 查看 QQ 登陸后回跳的 Doc 請求,發(fā)現(xiàn) req 的 cookie 中有 token,應該是qq網站的token,卻帶過來被我獲取當做了自己的 token 用
解決:
改token名,token太通用了,改成udm_token
問題二:
依然存在返回401問題,具體時機為登錄后在個人中心頁刷新,接口返回401,在其它頁面刷新不會
線索:
- 查看刷新時的 Doc 請求,發(fā)現(xiàn)帶了兩個 udm_token,服務端取第一個來用,而第一個是過期了的。
- 在網絡中查看請求的兩個 udm_token,發(fā)現(xiàn)是兩個 path 下的,path 一個是 "/" 一個是 "my/"
- 個人中心頁地址是 /my/account,其它的頁面是單級地址例如 /me
- 猜測是有 udm_token 在 set 時被設置在了 my/ 下,而退出登錄刪除時并沒有刪除這個地址下的內容
- 查看 cookie-universal 源碼,發(fā)現(xiàn) set 方法默認帶 options = {path: '/'}
set(name = '', value = '', opts = { path: '/' }) {
if (isNeither) return
value = typeof value === 'object' ? JSON.stringify(value) : value
if (isServer) {
const cookies = getResponseCookies()
cookies.push(Cookie.serialize(name, value, opts))
setResponseCookie(cookies)
} else {
document.cookie = Cookie.serialize(name, value, opts)
}
}
- 在我的代碼中,存在傳入 options 的情況,options 中加入了 maxAge,卻沒有加入 path, 因此被錯誤地設置到了 /my 下
// 錯誤
this.$cookies.set('udm_token', token, {
maxAge: 60 * 60 * 24 * 7
})
解決:
在手動傳入 options 時一并添加 path: '/' 得以解決
this.$cookies.set('udm_token', token, {
maxAge: 60 * 60 * 24 * 7,
path: '/'
})
總結:
解決下來回頭看覺得問題挺蠢的,感嘆規(guī)范化代碼和好好看文檔的重要性。
不過掉坑掙扎爬出來的過程,也是分析解決問題過程,還熟悉了源碼和原理,收獲也不少,哈哈。