跨域问题(续)
此貼接上貼實(shí)踐解決跨域問(wèn)題的三種方式剖析
今天繼續(xù)做我的schub項(xiàng)目的時(shí)候,遇到了苦惱我一天的問(wèn)題,expresss-session沒(méi)有持久化,我在后端把登錄的狀態(tài)存在req的session里,下次發(fā)post的時(shí)候再發(fā)請(qǐng)求的時(shí)候req.session里面存的用戶的狀態(tài)的字段沒(méi)了。
我上次用到express-session的時(shí)候還是做得那個(gè)微博系統(tǒng),前后端雜糅的項(xiàng)目(node+ejs),那時(shí)候就沒(méi)遇到這個(gè)問(wèn)題,后來(lái)排查這個(gè)問(wèn)題的時(shí)候,google 網(wǎng)上有關(guān)express-session的項(xiàng)目,發(fā)現(xiàn)這些項(xiàng)目全是前后端在一起的架構(gòu),然后我就意識(shí)到一個(gè)問(wèn)題,前后端在一起域名和端口都是一致的,當(dāng)前后端分離在本地調(diào)試的時(shí)候,我處理了很多跨域問(wèn)題,那么現(xiàn)在,是不是由跨域問(wèn)題引起的。
我本地打印調(diào)試了fetch發(fā)送的請(qǐng)求,(因?yàn)榭缬蛎看握?qǐng)求發(fā)了一個(gè)option),發(fā)現(xiàn)每次的session都是新的,sessionId不同,那么怎么保持session會(huì)話一致呢。
后來(lái)差文檔,發(fā)現(xiàn):
對(duì)于跨域 XMLHttpRequest 或 Fetch 請(qǐng)求,瀏覽器不會(huì)發(fā)送身份憑證信息。如果要發(fā)送憑證信息,需要設(shè)置 XMLHttpRequest 的某個(gè)特殊標(biāo)志位。對(duì)于附帶身份憑證的請(qǐng)求,服務(wù)器不得設(shè)置 Access-Control-Allow-Origin 的值為“*”。用了Access-Control-Allow-Credentials: true,就不能設(shè)置Access-Control-Allow-Origin:'*'了。所以可以設(shè)置,當(dāng)A用戶進(jìn)來(lái)的時(shí)候,我們?cè)O(shè)置A用戶為白名單就好,同理B用戶也是。也就是說(shuō),誰(shuí)訪問(wèn)就把誰(shuí)的域設(shè)置為白名單就可以了。
Access-Control-Allow-Origin: <origin> | *所以我的處理一般是:
app.all('/*', (req, res, next) => {res.setHeader('Access-Control-Allow-Origin', req.headers && req.headers.origin ? req.headers.origin : '*');res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie, Authorization');res.setHeader('Access-Control-Allow-Credentials', true);//post請(qǐng)求之前,會(huì)發(fā)送一個(gè)options的跨域請(qǐng)求if (req.method === 'OPTIONS') {res.sendStatus(200);} else {next()} })由于前端react里面請(qǐng)求是fetch發(fā)送的,fetch的原理就是xhr+promise,
那么fetch肯定也有這么一個(gè)維持身份憑證的消息頭,
看MDN:
XMLHttpRequest.withCredentials 屬性是一個(gè)Boolean類(lèi)型,它指示了是否該使用類(lèi)似cookies,authorization headers(頭部授權(quán))或者TLS客戶端證書(shū)這一類(lèi)資格證書(shū)來(lái)創(chuàng)建一個(gè)跨站點(diǎn)訪問(wèn)控制(cross-site Access-Control)請(qǐng)求。在同一個(gè)站點(diǎn)下使用withCredentials屬性是無(wú)效的。此外,這個(gè)指示也會(huì)被用做響應(yīng)中cookies 被忽視的標(biāo)示。默認(rèn)值是false。如果在發(fā)送來(lái)自其他域的XMLHttpRequest請(qǐng)求之前,未設(shè)置withCredentials 為true,那么就不能為它自己的域設(shè)置cookie值。而通過(guò)設(shè)置withCredentials 為true獲得的第三方cookies,將會(huì)依舊享受同源策略,因此不能被通過(guò)document.cookie或者從頭部相應(yīng)請(qǐng)求的腳本等訪問(wèn)。三點(diǎn)信息:
1.跨域訪問(wèn)中,只有帶上withCredentials=true才會(huì)允許跨域的請(qǐng)求中帶上自己cookie,(authorization)而cookie中是存有sessionId的,所以也是保持會(huì)話一致的前提。
2.同域名下的這個(gè)參數(shù)是無(wú)效的。
3.通過(guò)這種方法攜帶的cookie依然受同源策略的限制,我們不能直接通過(guò)前端手段或者腳本訪問(wèn)到改cookie。
所以我在react前端把所有的fetch的options中加上
credentials: 'include',即可。此時(shí)發(fā)現(xiàn)每次fetch請(qǐng)求的session是同一個(gè)了。
轉(zhuǎn)載于:https://www.cnblogs.com/zhangmingzhao/p/9448265.html
總結(jié)
- 上一篇: kali linux2.0下MariaD
- 下一篇: [转]工程师文化