CORS跨域限制以及预请求验证

CORS 的使用

创建两个服务器,进入对应目录,命令行 node server.js,node server2.js,启动服务器。

server.js 会读取 test.html,在8888端口显示,test.html发送跨域请求8887服务器,server2.js通过设置'Access-Control-Allow-Origin': 'http://127.0.0.1:8888'允许跨域。

浏览器认为localhost和127.0.0.1不同,所以本地用127.0.0.1

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8') // 注意设置 utf8,这样读取的是字符串,否则是二进制的数据
  response.writeHead(200, {
    'Content-Type': 'text/html' // 不设置的话,浏览器会直接显示,不解析;默认浏览器会加上
  })
  response.end(html)
}).listen(8888)

console.log('server listening on 8888')
复制代码
// server2.js
const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, { // 不设置这个头,浏览器还是会发送请求,并接收内容,浏览器检查head头,如果没有'Access-Control-Allow-Origin',并且设置为允许,浏览器会把本次请求返回的内容会略掉,并且报错。
    'Access-Control-Allow-Origin': 'http://127.0.0.1:8888', // 允许 8888 的域名访问,*也可以(不够安全)
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

添加多个头

通过判断 request.url 来判断是否添加不同的 head 头。

JSONP

浏览器允许 link img script中的src或href进行跨域请求,JSONP的原理就是在script标签中,加载链接,链接访问了服务器某个请求,并返回了内容,服务器返回的内容是可控的,可以在服务器返回内容中的script标签中写一段可执行的JS代码,然后调用JSONP发起请求的一些内容。

// test.html
<script src="http://127.0.0.1:8887/"></script>
复制代码

这样不设置8887的head头,也可以进行跨域,得到请求内容。

CORS跨域限制

主要包括 methods content-type 和 请求头的限制。

允许方法

默认允许方法 GET HEAD POST,其他的方法 PUT DELETE 默认是不允许的。

允许Content-Type

text/plain

multipart/form-data

application/x-www-form-urlencoded

除了这三种,其他的 Content-Type 也需要使用预请求验证后,才能发送。

其他限制

  • 请求头限制,自定义的请求头默认是不允许的,也需要验证;官方文档,关于请求头的详细信息https://fetch.spec.whatwg.org/#cors-safelisted-request-header
  • XMLHttpRequestUpload 对象均没有注册任何事件监听器(很少用)
  • 请求中没有使用 ReadableStream 对象(很少用)

CORS预请求

demo

8888下的 test.html 发送的请求携带了自定义请求头,从浏览器看请求发送成功,返回状态码200,但是浏览器会报错,不允许跨域,数据虽然返回,但被浏览器忽略了。

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8') 
  response.writeHead(200, {
    'Content-Type': 'text/html' 
  })
  response.end(html)
}).listen(8888)

console.log('server listening on 8888')
复制代码
// server2.js
const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, { 
    'Access-Control-Allow-Origin': '*'
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码
<script>
  fetch('http://localhost:8887', { // 发送请求
    method: 'POST',
    headers: { // 一个自定义的头
      'X-Test-Cors': '123'
    }
  })
</script>
复制代码

实现预请求

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, { 
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'X-Test-Cors' // 服务端添加允许自定义请求头
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

查看network,会发现多了一个请求文件localhost,它的 Request Method 请求方法是 OPTIONS,其他的很正常请求一样,通过 OPTIONS 请求获得服务端允许发送请求的认可。之后再实际发送 POST 请求。

允许其他请求方法

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, {
    'Access-Control-Allow-Origin': '*', 
    'Access-Control-Allow-Headers': 'X-Test-Cors',
    'Access-Control-Allow-Methods': 'POST, PUT, DELETE' // 允许使用被限制的请求方法
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

跨域请求时间

比如第一次请求,network观察文件,会有 Method 是 OPTIONS 的预请求文件,再次刷新网页发送请求,这个文件就不会再发送了,不会出现在 network 列表中。

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  response.writeHead(200, {
    'Access-Control-Allow-Origin': '*', 
    'Access-Control-Allow-Headers': 'X-Test-Cors',
    'Access-Control-Allow-Methods': 'POST, PUT, DELETE',
    'Access-Control-Max-Age': '1000' // 1000s之内,不需要再发送预请求进行验证了,时间内直接发正式请求
  })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')
复制代码

浏览器希望通过限制保证服务端的安全

转载于:https://juejin.im/post/5ba59cf25188255c46368578

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CORS跨域资源共享)是一种机制,允许网页从不同的域访问其资源。但是,CORS也可能导致一些安全问题,例如跨站请求伪造攻击(CSRF)和跨站脚本攻击(XSS)。因此,为了修复CORS漏洞,可以采取以下措施: 1. 限制Origin头:在服务器端,可以通过检查Request Header中的Origin头来判断请求是否来自可信域。如果请求的Origin头不在可信列表中,则返回错误响应。 2. 使用Access-Control-Allow-Origin头:在服务器端,可以设置Access-Control-Allow-Origin头为允许访问的域名列表,以控制哪些域可以访问资源。 3. 使用Access-Control-Allow-Credentials头:如果需要在跨域请求中使用cookie等凭证信息,则需要设置Access-Control-Allow-Credentials头为true,并在客户端设置withCredentials为true。 4. 限制请求方法:在服务器端,可以限制请求方法,以防止恶意请求。例如,只允许使用GET和POST方法。 5. 验证请求的来源:在服务器端,可以验证请求的来源,以确保请求来自可信的源。例如,可以检查Referer头或者使用Captcha等验证技术。 6. 使用安全的Cookie:在客户端,可以使用HttpOnly和Secure属性来保护cookie,以防止被窃取或篡改。 7. 定期更新软件:CORS漏洞通常是由于软件版本过旧或存在未修复的漏洞导致的。因此,定期更新软件是非常重要的。 以上是一些修复CORS漏洞的建议。除此之外,还需要对应用程序进行全面的安全测试,以确保没有其他漏洞存在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值