【Go开源宝藏】CORS 跨域 与 CSRF攻击 中间件

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金

在这里插入图片描述

  1. 什么是跨域

当一个请求url的协议域名端口三者之间任意一个与当前页面url不同即为跨域

当前页面url 被请求页面url 是否跨域 原因
www.test.com/ www.test.com/index.html 同源(协议、域名、端口号相同)
www.test.com/ www.test.com/index.html 跨域 协议不同(http/https)
www.test.com/ www.baidu.com/ 跨域 主域名不同(test/baidu)
www.test.com/ blog.test.com/ 跨域 子域名不同(www/blog)
www.test.com:8080/ www.test.com:7001/ 跨域 端口号不同(8080/7001)

因为域的不一致,与此同时由于安全问题,请求就会受到同源策略限制

通常,浏览器会对跨域请求作出限制。
浏览器之所以要对跨域请求作出限制,是出于安全方面的考虑,因为跨域请求有可能被不法分子利用来发动 CSRF攻击。

  1. CSRF攻击

2.1 CSRF说明

CSRF(Cross-site request forgery)中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。

2.1 原理

​ CSRF 攻击的原理大致描述如下:

  1. 有两个网站,其中A网站是真实受信任的网站,而B网站是危险网站。
  2. 在用户登陆了受信任的A网站是,本地会存储A网站相关的Cookie,并且浏览器也维护这一个Session会话。
  3. 这时,如果用户在没有登出A网站的情况下访问危险网站B,那么危险网站B就可以模拟发出一个对A网站的请求(跨域请求)对A网站进行操作
  4. 而在A网站的角度来看是并不知道请求是由B网站发出来的(Session和Cookie均为A网站的),这时便成功发动一次 CSRF 攻击。

​ 因而 CSRF 攻击可以简单理解为:攻击者盗用了你的身份,以你的名义发送请求

CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账……造成的问题包括:个人隐私泄露以及财产安全。

  1. CORS

3.1 简介

跨源资源共享 Cross-Origin Resource Sharing(CORS) 是一个新的 W3C 标准,它新增的一组HTTP首部字段,允许服务端其声明哪些源站有权限访问哪些资源。

换言之,它允许浏览器向声明了 CORS 的跨域服务器,发出 XMLHttpReuest 请求,从而克服 Ajax 只能同源使用的限制

简单介绍一下CORS中新增的 HTTP 首部字段

  • Access-Control-Allow-Origin
    响应首部中可以携带这个头部表示服务器允许哪些域可以访问该资源
1
go复制代码c.Header("Access-Control-Allow-Origin", "*")
  • Access-Control-Allow-Methods
    预检请求的响应,指明实际请求所允许使用的HTTP方法
1
go复制代码c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
  • Access-Control-Allow-Headers
    首部字段用于预检请求的响应,指明了实际请求中允许携带的首部字段
1
go复制代码c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
  • Access-Control-Max-Age
    首部字段用于预检请求的响应,指定了预检请求能够被缓存多久。
1
go复制代码c.Header("Access-Control-Max-Age", "172800")
  • Access-Control-Allow-Credentials
    首部字段用于预检请求的响应,指明实际请求所允许使用的HTTP方法。
1
go复制代码c.Header("Access-Control-Allow-Credentials", "false")

3.2 引用

在中间件中设置编写即可!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
go复制代码func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method //请求方法
origin := c.Request.Header.Get("Origin") //请求头部
var headerKeys []string // 声明请求头keys
for k := range c.Request.Header {
headerKeys = append(headerKeys, k)
}
headerStr := strings.Join(headerKeys, ", ")
if headerStr != "" {
headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
} else {
headerStr = "access-control-allow-origin, access-control-allow-headers"
}
if origin != "" {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Origin", "*")
// 这是允许访问所有域
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
//服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
// header的类型
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
// 允许跨域设置,可以返回其他子段
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar")
// 跨域关键设置 让浏览器可以解析
c.Header("Access-Control-Max-Age", "172800")
// 缓存请求信息 单位为秒
c.Header("Access-Control-Allow-Credentials", "false")
// 跨域请求是否需要带cookie信息 默认设置为true
c.Set("content-type", "application/json")
// 设置返回格式是json
}
//放行所有OPTIONS方法
if method == "OPTIONS" {
c.JSON(http.StatusOK, "Options Request!")
}
c.Next() // 处理请求
}
}

配合gin框架使用

1
2
go复制代码	r:=gin.Default()
r.Use(middleware.Cors())

参考文献
1、www.jianshu.com/p/f880878c1…
2、blog.csdn.net/qq_38128179…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%