跨域設(shè)置Cookie失效問題解決方案原理分析
問題出現(xiàn)場景
在做登錄功能時,想把用戶的信息通過Set-cookie在客戶端設(shè)置cookie信息。
1.服務(wù)端通過cors中間件實(shí)現(xiàn)接口跨域訪問、koa-session-minimal實(shí)現(xiàn)cookie的設(shè)置。
代碼實(shí)現(xiàn)如下
const session = require('koa-session-minimal')
const cors = require('@koa/cors');
// app.js
const app = new Koa()
app.use(cors())
// 存放sessionId的cookie配置, 相關(guān)的一些字段配置說明可以查看http協(xié)議。
let cookie = {
maxAge: 2 * 60 * 1000, // cookie有效時長
expires: new Date('2022-08-26'), // cookie失效時間
path: '/', // 寫cookie所在的路徑
domain: 'localhost', // 寫cookie所在的域名
httpOnly: false, // 是否只用于http請求中獲取
overwrite: false, // 是否允許重寫
// secure: '',
sameSite: 'strict',
// signed: '',
}
// 使用session中間件
app.use(session({
key: 'SESSION_ID',
cookie: cookie
}))
登陸接口相關(guān)代碼
// login接口
// ...
if (!err) {
ctx.session = {
user_id: adminId,
count: 0
}
ctx.response.status = 200;
// ...
}
// ...
一切進(jìn)展順利,接口響應(yīng)成功,響應(yīng)頭也有我們設(shè)置的cookie字段。但是事情的背后往往沒有這么簡單,當(dāng)我去看Application中的Cookie信息時,發(fā)現(xiàn)怎么都找不到我想要的SESSION_ID字段,百思不得姐。


問題出現(xiàn)的解決方案如下
1.通過查閱一些資料后,發(fā)現(xiàn)瀏覽器的同源策略是對跨域的cookie有做一些限制的。其中Access-Control-Allow-Credentials字段就控制著對跨域cookie的設(shè)置。
Access-Control-Allow-Credentials 響應(yīng)頭用于在請求要求包含 credentials(Request.credentials 的值為 include)時,告知瀏覽器是否可以將對請求的響應(yīng)暴露給前端 JavaScript 代碼。
當(dāng)請求的 credentials 模式為 include 時,瀏覽器僅在響應(yīng)標(biāo)頭 Access-Control-Allow-Credentials 的值為 true 的情況下將響應(yīng)暴露給前端的 JavaScript 代碼。(這段文字是來自MDN文檔)。
我理解是只有開啟后,瀏覽器在讀取到響應(yīng)頭的Set-cookie字段時,才能將cookie字段設(shè)置于瀏覽器中。于是我根據(jù)cors使用文檔做出了代碼上的調(diào)整:
const app = new Koa()
const koaOptions = {
origin: 'http://localhost:9529',
credentials: true
};
app.use(cors(koaOptions))
2.于是本人胸有成竹的開啟了新一遍的流程測試,想必這次是能成功的。經(jīng)過了幾S的流程測試之后,我得到了一個結(jié)果:失敗是成功之母。
顯然我們這次又未在Application的cookie中找到我們想要的SESSION_ID字段,我再次沉浸式的翻閱了MDN的cookie相關(guān)文檔。
3.發(fā)現(xiàn)文檔中其實(shí)是有寫到:Access-Control-Allow-Credentials 標(biāo)頭需要與 XMLHttpRequest.withCredentials 或 Fetch API 的 Request() 構(gòu)造函數(shù)中的 credentials 選項(xiàng)結(jié)合使用。
Credentials 必須在前后端都被配置(即 Access-Control-Allow-Credentials header 和 XHR 或 Fetch request 中都要配置)才能使帶 credentials 的 CORS 請求成功。
XMLHttpRequest.withCredentials 屬性是一個布爾類型,它指示了是否該使用類似 Cookies、Authorization Headers (頭部授權(quán)) 或者 TLS 客戶端證書這一類資格證書來創(chuàng)建一個跨站點(diǎn)訪問控制(cross-site Access-Control)請求。
在同一個站點(diǎn)下使用 withCredentials 屬性是無效的。此外也會被用做響應(yīng)中 Cookies 被忽視的標(biāo)示。默認(rèn)值是 false。
如果在發(fā)送來自其他域的 XMLHttpRequest 請求之前,未設(shè)置withCredentials 為 true,那么就不能為它自己的域設(shè)置 Cookie 值。
而通過設(shè)置 withCredentials 為 true 獲得的第三方 Cookies,將會依舊享受同源策略,因此不能被通過document.cookie或者從頭部相應(yīng)請求的腳本等訪問。(這段文字是來自MDN文檔)。
4.根據(jù)以上信息,我調(diào)整了前端項(xiàng)目封裝的request模塊代碼,將withCredentiaols設(shè)置成了true:
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
再一次的進(jìn)行我們的流程測試,果然功夫不負(fù)有心人,終于是在Application中看到了心心念的SESSION_ID:


反思和結(jié)語
踏破鐵鞋無覓處,得來全不費(fèi)工夫。我們在遇見問題的時候,應(yīng)該盡量從問題的本質(zhì)出發(fā)尋找突破口,試著從另一個角度切入。
其次就是對相關(guān)知識的掌握程度,我在這次的遇見問題和解決問題的過程中做出了反思,確實(shí)有尋找到突破口:瀏覽器的同源策略限制。
但是對其相關(guān)的策略掌握不夠深入,導(dǎo)致花費(fèi)了比正常多幾倍的時間去解決問題,經(jīng)過這次的文檔查閱,我對跨域設(shè)置cookie以及瀏覽器同源限制策略,有了更進(jìn)一步的認(rèn)知。
以上就是跨域設(shè)置Cookie失效問題解決方案原理分析的詳細(xì)內(nèi)容,更多關(guān)于跨域設(shè)置Cookie失效解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
動態(tài)引入DynamicImport實(shí)現(xiàn)原理
這篇文章主要為大家介紹了動態(tài)引入DynamicImport實(shí)現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
JS前端使用canvas動態(tài)繪制函數(shù)曲線示例詳解
這篇文章主要為大家介紹了JS前端使用canvas畫函數(shù)曲線的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
fabric.js圖層功能獨(dú)立顯隱?添加?刪除?預(yù)覽實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了fabric.js圖層功能獨(dú)立顯隱?添加?刪除?預(yù)覽實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
微信小程序報錯:this.setData is not a function的解決辦法
這篇文章主要介紹了微信小程序報錯:this.setData is not a function的解決辦法的相關(guān)資料,希望通過本文能幫助到大家解決這樣類似的問題,需要的朋友可以參考下2017-09-09
微信小程序 開發(fā)之滑塊視圖容器(swiper)詳解及實(shí)例代碼
這篇文章主要介紹了微信小程序 開發(fā)之滑塊視圖容器(swiper)詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02

