摘要:同源策略禁止使用對(duì)象向不同源的服務(wù)器地址發(fā)起請(qǐng)求。借助于決解同源策略決解同源策略,新方案跨域資源共享這里講的重點(diǎn)跨域資源共享提供的標(biāo)準(zhǔn)跨域解決方案,是一個(gè)由瀏覽器共同遵循的一套控制策略,通過(guò)的來(lái)進(jìn)行交互主要通過(guò)后端來(lái)設(shè)置配置項(xiàng)。
了解下同源策略
源(origin)*:就是協(xié)議、域名和端口號(hào);
同源: 就是源相同,即協(xié)議、域名和端口完全相同;
同源策略:同源策略是瀏覽器的一個(gè)安全功能,不同源的客戶端腳本在沒(méi)有明確授權(quán)的情況下,不能讀寫對(duì)方資源;
同源策略的分類:
DOM 同源策略:即針對(duì)于DOM,禁止對(duì)不同源頁(yè)面的DOM進(jìn)行操作;如不同域名的 iframe 是限制互相訪問(wèn)。
XMLHttpRequest 同源策略:禁止使用 XHR 對(duì)象向不同源的服務(wù)器地址發(fā)起 HTTP 請(qǐng)求。
不受同源策略限制:
頁(yè)面中的鏈接,重定向以及表單提交(因?yàn)楸韱翁峤唬瑪?shù)據(jù)提交到action域后,本身頁(yè)面就和其沒(méi)有關(guān)系了,不會(huì)管請(qǐng)求結(jié)果,后面操作都交給了action里面的域)是不會(huì)受到同源策略限制的。
資源的引入不受限制,但是js不能讀寫加載的內(nèi)容:如嵌入到頁(yè)面中的,,,等
如果沒(méi)有 DOM 同源策略:那么就沒(méi)有啥xss的研究了,因?yàn)槟愕木W(wǎng)站將不是你的網(wǎng)站,而是大家的,誰(shuí)都可以寫個(gè)代碼操作你的網(wǎng)站界面
如果沒(méi)有XMLHttpRequest 同源策略,那么就可以很輕易的進(jìn)行CSRF(跨站請(qǐng)求偽造)攻擊:
用戶登錄了自己的網(wǎng)站頁(yè)面 a.com,cookie中添加了用戶標(biāo)識(shí)。
用戶瀏覽了惡意頁(yè)面 b.com,執(zhí)行了頁(yè)面中的惡意 AJAX 請(qǐng)求代碼。
b.com 向 a.com發(fā)起 AJAX HTTP 請(qǐng)求,請(qǐng)求會(huì)默認(rèn)把 a.com對(duì)應(yīng)cookie也同時(shí)發(fā)送過(guò)去。
a.com從發(fā)送的 cookie 中提取用戶標(biāo)識(shí),驗(yàn)證用戶無(wú)誤,response 中返回請(qǐng)求數(shù)據(jù);數(shù)據(jù)就泄露了。而且由于Ajax在后臺(tái)執(zhí)行,這一過(guò)程用戶是無(wú)法感知的。
(附)有了XMLHttpRequest 同源策略就可以限制CSRF攻擊?別忘了還有不受同源策略的:表單提交和資源引入,(安全問(wèn)題下期在研究)
跨域決解方案
JSONP 跨域:借鑒于 script 標(biāo)簽不受瀏覽器同源策略的影響,允許跨域引用資源;因此可以通過(guò)動(dòng)態(tài)創(chuàng)建 script 標(biāo)簽,然后利用 src 屬性進(jìn)行跨域;
缺點(diǎn):
所有網(wǎng)站都可以拿到數(shù)據(jù),存在安全性問(wèn)題,需要網(wǎng)站雙方商議基礎(chǔ)token的身份驗(yàn)證。
只能是GET,不能POST。
可能被注入惡意代碼,篡改頁(yè)面內(nèi)容,可以采用字符串過(guò)濾來(lái)規(guī)避此問(wèn)題。
服務(wù)器代理:瀏覽器有跨域限制,但是服務(wù)器不存在跨域問(wèn)題,所以可以由服務(wù)器請(qǐng)求所要域的資源再返回給客戶端。
document.domain、window.name 、location.hash:借助于iframe決解DOM同源策略
postMessage:決解DOM同源策略,新方案
CORS(跨域資源共享):這里講的重點(diǎn)
CORS(跨域資源共享)HTML5 提供的標(biāo)準(zhǔn)跨域解決方案,是一個(gè)由瀏覽器共同遵循的一套控制策略,通過(guò)HTTP的Header來(lái)進(jìn)行交互;主要通過(guò)后端來(lái)設(shè)置CORS配置項(xiàng)。
CORS簡(jiǎn)單使用之前說(shuō)得CORS跨域,嗯嗯,后端設(shè)置Access-Control-Allow-Origin:*|[或具體的域名]就好了;
第一次嘗試:
app.use(async(ctx,next) => { ctx.set({ "Access-Control-Allow-Origin": "http://localhost:8088" })
發(fā)現(xiàn)有些請(qǐng)求可以成功,但是有些還是會(huì)報(bào)錯(cuò):
請(qǐng)求被同源策略阻止,預(yù)請(qǐng)求的響應(yīng)沒(méi)有通過(guò)檢查:http返回的不是ok?
并且發(fā)現(xiàn)發(fā)送的是OPTIONS請(qǐng)求:
發(fā)現(xiàn):CORS規(guī)范將請(qǐng)求分為兩種類型,一種是簡(jiǎn)單請(qǐng)求,另外一種是帶預(yù)檢的非簡(jiǎn)單請(qǐng)求
簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求
瀏覽器發(fā)送跨域請(qǐng)求判斷方式:
瀏覽器在發(fā)送跨域請(qǐng)求的時(shí)候,會(huì)先判斷下是簡(jiǎn)單請(qǐng)求還是非簡(jiǎn)單請(qǐng)求,如果是簡(jiǎn)單請(qǐng)求,就先執(zhí)行服務(wù)端程序,然后瀏覽器才會(huì)判斷是否跨域;
而對(duì)于非簡(jiǎn)單請(qǐng)求,瀏覽器會(huì)在發(fā)送實(shí)際請(qǐng)求之前先發(fā)送一個(gè)OPTIONS的HTTP請(qǐng)求來(lái)判斷服務(wù)器是否能接受該跨域請(qǐng)求;如果不能接受的話,瀏覽器會(huì)直接阻止接下來(lái)實(shí)際請(qǐng)求的發(fā)生。
什么是簡(jiǎn)單請(qǐng)求
請(qǐng)求方法是如下之一:
GET
HEAD
POST
所有的Header都只包含如下列表中(沒(méi)有自定義header):
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
除此之外都是非簡(jiǎn)單請(qǐng)求
CORS非簡(jiǎn)單請(qǐng)求配置須知正如上圖報(bào)錯(cuò)顯示,對(duì)于非簡(jiǎn)單請(qǐng)求,瀏覽器會(huì)先發(fā)送options預(yù)檢,預(yù)檢通過(guò)后才會(huì)發(fā)送真是的請(qǐng)求;
發(fā)送options預(yù)檢請(qǐng)求將關(guān)于接下來(lái)的真實(shí)請(qǐng)求的信息給服務(wù)器:
Origin:請(qǐng)求的源域信息 Access-Control-Request-Method:接下來(lái)的請(qǐng)求類型,如POST、GET等 Access-Control-Request-Headers:接下來(lái)的請(qǐng)求中包含的用戶顯式設(shè)置的Header列表
服務(wù)器端收到請(qǐng)求之后,會(huì)根據(jù)附帶的信息來(lái)判斷是否允許該跨域請(qǐng)求,通過(guò)Header返回信息:
Access-Control-Allow-Origin:允許跨域的Origin列表 Access-Control-Allow-Methods:允許跨域的方法列表 Access-Control-Allow-Headers:允許跨域的Header列表,防止遺漏Header,因此建議沒(méi)有特殊需求的情況下設(shè)置為* Access-Control-Expose-Headers:允許暴露給JavaScript代碼的Header列表 Access-Control-Max-Age:最大的瀏覽器預(yù)檢請(qǐng)求緩存時(shí)間,單位為sCORS完整配置
koa配置CORS跨域資源共享中間件:
const cors = (origin) => { return async (ctx, next) => { ctx.set({ "Access-Control-Allow-Origin": origin, //允許的源 }) // 預(yù)檢請(qǐng)求 if (ctx.request.method == "OPTIONS") { ctx.set({ "Access-Control-Allow-Methods": "OPTIONS,HEAD,DELETE,GET,PUT,POST", //支持跨域的方法 "Access-Control-Allow-Headers": "*", //允許的頭 "Access-Control-Max-Age":10000, // 預(yù)檢請(qǐng)求緩存時(shí)間 // 如果服務(wù)器設(shè)置Access-Control-Allow-Credentials為true,那么就不能再設(shè)置Access-Control-Allow-Origin為*,必須用具體的域名 "Access-Control-Allow-Credentials":true // 跨域請(qǐng)求攜帶身份信息(Credential,例如Cookie或者HTTP認(rèn)證信息) }); ctx.send(null, "預(yù)檢請(qǐng)求") } else { // 真實(shí)請(qǐng)求 await next() } } } export default cors
現(xiàn)在不管是簡(jiǎn)單請(qǐng)求還是非簡(jiǎn)單請(qǐng)求都可以跨域訪問(wèn)啦~
跨域時(shí)如何處理cookie
cookie:
我們知道http時(shí)無(wú)狀態(tài)的,所以在維持用戶狀態(tài)時(shí),我們一般會(huì)使用cookie;
cookie每次同源請(qǐng)求都會(huì)攜帶;但是跨域時(shí)cookie是不會(huì)進(jìn)行攜帶發(fā)送的;
問(wèn)題:
由于cookie對(duì)于不同源是不能進(jìn)行操作的;這就導(dǎo)致,服務(wù)器無(wú)法進(jìn)行cookie設(shè)置,瀏覽器也沒(méi)法攜帶給服務(wù)器(場(chǎng)景:用戶登錄進(jìn)行登錄操作后,發(fā)現(xiàn)響應(yīng)中有set-cookie但是,瀏覽器cookie并沒(méi)有相應(yīng)的cookie)
決解:
瀏覽器請(qǐng)求設(shè)置withCredentials為true即可讓該跨域請(qǐng)求攜帶 Cookie;使用axios配置axios.defaults.withCredentials = true
服務(wù)器設(shè)置Access-Control-Allow-Credentials=true允許跨域請(qǐng)求攜帶 Cookie
“積跬步、行千里”—— 持續(xù)更新中~,喜歡的話留下個(gè)贊和關(guān)注哦!
往期經(jīng)典好文:
服務(wù)器(CentOS)安裝配置mongodb
Koa日志中間件封裝開(kāi)發(fā)(log4js)
團(tuán)隊(duì)合作必備的Git操作
使用pm2部署node生產(chǎn)環(huán)境
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/109108.html
摘要:瀏覽器的同源策略固然保障了互聯(lián)網(wǎng)世界的數(shù)據(jù)隱私與數(shù)據(jù)安全,但是如果當(dāng)我們需要使用跨域請(qǐng)求資源時(shí),同源策略又會(huì)成為開(kāi)發(fā)者的阻礙。我們之前提到過(guò),如果想要繞過(guò)瀏覽器同源策略,實(shí)現(xiàn)使用技術(shù)跨域獲取資源,需要服務(wù)端和客戶端的協(xié)同合作。 瀏覽器的同源策略固然保障了互聯(lián)網(wǎng)世界的數(shù)據(jù)隱私與數(shù)據(jù)安全,但是如果當(dāng)我們需要使用AJAX跨域請(qǐng)求資源時(shí),同源策略又會(huì)成為開(kāi)發(fā)者的阻礙。在本文中,我們會(huì)簡(jiǎn)單介紹需...
摘要:跨域正確的打開(kāi)方式經(jīng)過(guò)對(duì)同源策略的了解,我們應(yīng)該要消除對(duì)瀏覽器的誤解,同源策略是瀏覽器做的一件好事,是用來(lái)防御來(lái)自邪門歪道的攻擊,但總不能為了不讓壞人進(jìn)門而把全部人都拒之門外吧。 跨域這兩個(gè)字就像一塊狗皮膏藥一樣黏在每一個(gè)前端開(kāi)發(fā)者身上,無(wú)論你在工作上或者面試中無(wú)可避免會(huì)遇到這個(gè)問(wèn)題。為了應(yīng)付面試,我每次都隨便背幾個(gè)方案,也不知道為什么要這樣干,反正面完就可以扔了,我想工作上也不會(huì)用到...
摘要:關(guān)于,強(qiáng)烈推薦閱讀跨域資源共享詳解阮一峰另外,這里也整理了一個(gè)實(shí)現(xiàn)原理圖簡(jiǎn)化版如何判斷是否是簡(jiǎn)單請(qǐng)求瀏覽器將請(qǐng)求分成兩類簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求。 前言 從剛接觸前端開(kāi)發(fā)起,跨域這個(gè)詞就一直以很高的頻率在身邊重復(fù)出現(xiàn),一直到現(xiàn)在,已經(jīng)調(diào)試過(guò)N個(gè)跨域相關(guān)的問(wèn)題了,16年時(shí)也整理過(guò)一篇相關(guān)文章,但是感覺(jué)還是差了點(diǎn)什么,于是現(xiàn)在重新梳理了一下。 個(gè)人見(jiàn)識(shí)有限,如有差錯(cuò),請(qǐng)多多見(jiàn)諒,歡迎提出iss...
摘要:在中,在不同的域名下面進(jìn)行數(shù)據(jù)交互,就會(huì)遇到跨域問(wèn)題,說(shuō)到跨域首先要從同源說(shuō)起,瀏覽器為了提供一種安全的運(yùn)行環(huán)境,各個(gè)瀏覽器廠商協(xié)定使用同源策略。在上面說(shuō)過(guò)是不受同源策略限制的,但是出于安全原因,瀏覽器限制從腳本內(nèi)發(fā)起的跨源請(qǐng)求。 對(duì)于前端開(kāi)發(fā)來(lái)說(shuō)跨域應(yīng)該是最不陌生的問(wèn)題了,無(wú)論是開(kāi)發(fā)過(guò)程中還是在面試過(guò)程中都是一個(gè)經(jīng)常遇到的一個(gè)問(wèn)題,在開(kāi)發(fā)過(guò)程中遇到這個(gè)問(wèn)題的話一般都是找后端同學(xué)去解決...
閱讀 2306·2021-11-23 09:51
閱讀 3781·2021-10-20 13:49
閱讀 1776·2021-09-06 15:13
閱讀 1882·2021-09-06 15:02
閱讀 3354·2021-09-02 15:11
閱讀 962·2019-08-29 15:37
閱讀 1801·2019-08-29 13:24
閱讀 2323·2019-08-29 11:28