同源策略跟跨域简述

218 阅读3分钟

什么是同源?

域名、协议、端口完全一致即为同源

什么是同源的策略?

策略主要是限制js的能力

  • 1、无法读取非同源的cookie(token值) storage(存储) indexDb(浏览器的离线资源)

  • 2、无法读取非同源的Dom

  • 3、无法发送非同源的AJAX,更加准确的说是发送了请求,但是被浏览器拦截了

跨域.png

为什么会有同源策略?

为了保护用户的数据安全

  • 1、为了防止恶意网页可以获取其他网站的本地数据

  • 2、为了防止恶意网站iframe(在网站里嵌套另一个网站,这个网站称为iframe)其他网站的时候,获取数据

  • 3、为了防止恶意网站在自己网站有访问其他网站的权力,以免通过cookie免登,拿到数据

常见的恶意攻击

1、XSS攻击

什么是XSS攻击?

XSS攻击是一种 代码注入攻击 ,通过恶意注入脚本在浏览器运行,然后盗取用户的信息

XSS的本质是什么?

本质:因为浏览器没有过滤代码,当恶意代码跟正常代码混在一起时,浏览器也会执行这些恶意代码,导致数据被盗取

怎么防范XSS攻击

1、对用户输入框进行过滤,对 < 等符号进行转码操作 如:<===&It

2、使用CSP(白名单)直接告诉浏览器,那些是可以执行的

3、在Cookie信息中添加httpOnly,禁止在document.cookie中获取cookie,对一些敏感信息进行保护

2、CSRF攻击

什么是CSRF攻击

CSRF攻击是一种跨站请求伪造攻击 利用用户的登录状态发送跨站请求 来盗取用户信息

CSRF攻击的本质是什么?

本质:利用cookie在同源请求种携带发送给服务器的特点,来实现冒充用户

如何防范CSRF攻击

1、验证请求来源:服务器根据Http请求头中的Origin或Referer属性来判断是否允许访问的站点,从而对请求进行过滤,优先判断Origin,如果两个都不存在,就直接阻止请求

origin:记录了域名信息,没有具体的URL路径,post请求才会有

Origin: https:*//juejin.cn

Referer:记录了请求是从哪个链接跳过来的并且包含了路径信息,也就是来源地址,所有请求都会有。不过这家伙不太可靠,所以后来又新增了Origin属性

Referer: https://juejin.cn/editor/drafts/xxxx

2、在Cookie信息中添加SameSite属性,这个属性有三个值:

strict:严格模式,完全禁止使用Cookie

lax:宽松模式,允许部分情况使用Cookie,跨域的都行,a标签跳转,link标签,GET提交表单

none:任何情况下都会发送Cookie,但必须同时设置Secure属性,意思是需要安全上下文,Cookie 只能通过https发送,否则无效

Chrome 80之前默认值是none,之后是lax

Set-Cookie: widget_session=123456*; SameSite=None; Secure

3、Token验证

服务器向用户返回一个随机数Token,再次请求时在请求头中以参数的形式添加入这个Token,然后服务器验证这个Token,如果没有或者内容不正确,就拒绝请求。缺点是

每个请求都得添加比较繁琐

单方面验证Cookie可能会被冒用,

如果网站不止一台服务器,通过负载均衡转到了其他服务器的话,其他所有服务器中的Session中都得保留Token,不然就验证不了了

什么是跨域

跨域,是指通过一定的方法方式去访问不同源的页面,并获取数据

为什么会有跨域

它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。

如何实现跨域

1、CORS(后端)

目前最主流、最简单的方式,让后端设置响应头,允许资源共享

//调用方法创建一个服务器
  const app = express()
//解析json格式的请求体
  app.use(express.json())
//解析查询字符串格式的情趣 
  app.use(exoress.urlencoded({extended:true}))
//第一种: 使用中间件函数来设置cors允许资源共享
  app.use((req.res.next)=>{
    //设置响应头 告诉浏览器任何地址都可以访问这个接口
    res.setHeader('Access-Cosntrol-Allow-Origin','*')
    //告诉浏览器支持这些方式
    res.setHeader('Access-Cosntrol-Allow-Methods','GET,POST,DELETE,PUT')
    next()
  })
//第二种 推荐使用插件
  const cors = require('cors')
  app.use(cors())

设置成功之后显示

CORs.png

2、JSONP(前后端通用)

使用原理:通过script标签的src来发请求没有跨域限制来获取资源

注意:JSONP只支持get请求,不支持post,请求回来的东西当做js来执行

3.第三种:Nginx 【后端=>反向代理】

这个主要是后端去进行操作的

4、Proxy(前端) 反向代理

使用场景:只使用于本地开发环境,上线了解决不了

proxy.png

vue-cli脚手架工具搭建项目

vue.config.js配置文件中

![正向代理](C:\Users\admin\Desktop\手写面试资料\同源策略跨域\img\正向代理.png)module.exports = {
  devServer: {
    // 代理配置
    proxy: {
        // 如果请求地址以/api打头,就出触发代理机制
        '/api': {
          target: 'http://localhost:3000' // 要代理的真实接口地址
           // http://localhost:9588/api/login -> http://localhost:3000/api/login
        }
      }
    }
  }
}
复制代码

通过axios发请求配置根路径

axios.defaults.baseURL='/api'

修改配置之后,一定要重启前端项目,跨域解决

正向代理和反向代理的区别

代理.png

正向代理(origin server)

举个例子:我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。

反向代理(Reverse Proxy)

举个例子:我是一个用户,我访问了一个服务器,但是我不知道,我访问的服务器,其实是目标服务器的代理。是目标服务器把数据给了代理,然后我再从代理手中获得了数据