故事背景
前端用的 vue + axios
,
後端用的是 ko2
,用 koa-passport
+ passport-local
幫我處理登入登出,用 koa-generic-session
處理session, koa2-cors
處理跨域
問題描述
今天做登入的時候,發現 介面呼叫正常,資料正常傳遞,redis裡也有儲存相應值
唯獨前端頁面一直沒有設定上cookies,無法儲存登入狀態。
令人崩潰的解決過程
之前在測試功能的時候,能看見cookie被設定上了,然後我就以為是我這幾個庫沒寫對,翻騰來翻騰去,怎麼搞都不對,明明和網上的一模一樣,但就是拿不到cookie。 搗鼓了幾個小時,心態都崩了。
後來又重新起了一個專案A,直接設定cookie,直接瀏覽器訪問介面,cookie看見了。
用前端呼叫這個介面,cookie還是有(這裡忘記清除cookie記錄了,本地跑的時候都是localhost)(暴躁老哥)
然後又陷入 懷疑呼叫庫api出錯的死迴圈(崩潰邊緣)
然後又試了一下前端呼叫專案A的介面,cookie沒了?(清過cookie), 驚了,怎麼一會兒有一會兒沒的。
然後多次測試,總算髮現,我直接訪問介面能設定上cookie,但是前端請求拿不到。
ok,總算找到真正的原因了,而暴躁老哥到這一步的時候已經從下午搞到晚上了。
參考:
非空騎跡 - React,koa2前後端分離專案涉及cookie傳遞的方法
liyuling52011 - Vue 加入 withCredentials 後無法進行跨域請求
為什麼會有這樣的問題?
前端 localhost:8080 訪問後端 localhost:3000 會出現跨域的問題,我採用的是cors來解決。
但是同時也產生了無法傳遞cookies的情況,原因如下
預設情況下,跨源請求不提供憑據(cookie、HTTP認證及客戶端SSL證明等)
如果傳送的是帶憑據的請求,但伺服器的相應中沒有相關的頭部,那麼瀏覽器就不會把相應內容交給JavaScript,請求就無法得到結果的資料(瀏覽器得到了,但是我們請求的方法得不到,因為被瀏覽器攔截了)
如何解決
為此,在後端 CORS處理 時,設定相應的Header:
// 響應頭表示是否可以將對請求的響應暴露給頁面
Access-Control-Allow-Credentials: true
// 允許跨域操作的具體域名
Access-Control-Allow-Origin: "http://localhost:8080"
// 允許跨域的HTTP方法
Access-Control-Allow-Methods: ["GET","POST","DELETE"]
// 列出將會在正式請求的 Access-Control-Expose-Headers 欄位中出現的首部資訊
Access-Control-Allow-Headers: ["Content-Type", "Authorization", "Accept"]
複製程式碼
然後在前端也作出如下處理:
// 表示跨域請求時是否需要使用憑證
axios.defaults.withCredentials = true
複製程式碼
@留一杯阿,經過這位老哥提醒,如果設定
Access-Control-Allow-Origin: *
,不管withCredentials
有沒有設定,cookie也帶不過去
問題解決
解決問題花了這麼久的時候,歸根到底,還是過於暴躁,心態崩盤,外加不紮實的計算機網路基礎。 :<