用于gin框架的CORS中间件,解决身份凭证和通配符不能同时设置问题,可同时配置附带身份凭证的请求和*通配符,chrome插件CORS跨域请求通配符

11 篇文章 0 订阅
2 篇文章 0 订阅

用于gin框架的CORS中间件(当然,用在其他的框架和语言中相应的Header头设置和配置信息和应用原理都是一样的),解决Access-Control-Allow-Credentials  true身份凭证和 Access-Control-Allow-Origin: <origin> | 通配符不能同时设置问题,可同时配置附带身份凭证的请求和*通配符,以及在chrome插件中访问远程CORS跨域请求通配符问题等

yaml配置信息

注意修改相关的origin为你自己的, chrome插件的ID获取方式见  http跨域网络请求中的CORS(跨源资源共享) 那些事 -- HTTP跨域请求, chrome插件跨域请求使用详解, origin格式,origin通配符等-CSDN博客

app:
  baseUrl: http://localhost:8080

# 安全配置
security:
  # api接口允许跨域调用的origin列表 格式 {scheme}://{域名端口或扩展ID} 可以使用通配符 * 或者? , 注意域名最后不带/斜杠
  corsAllowOrigins:
  - "http://localhost"
  - "http://localhost:8080"
  - "*.tekin.cn"
  - "*.yunnan.ws"
  - "chrome-extension://*" # 这个是在chrome扩展里面调用的域 * 表示允许所有的扩展调用, 只允许指定扩展,如: "chrome-extension://iflfjlikpkacloanbaaokocoafabjndg"
  corsAllowHeaders: "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id"

gin CORS中间件实现代码

 注意下面的代码中使用了viper来读取yaml中的配置信息,如果你使用其他配置信息读取方式,只需要修改viper相关的配置信息读取代码即可。

strutils字符串模式匹配工具库安装: go get -u github.com/tekintian/strutils

package middleware

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/tekintian/strutils"
    "github.com/spf13/viper"
)
// gin CORS middleware	应用于gin框架的CORS中间件
// @author tekintian@gmail.com
func SecurityCORS(c *gin.Context) {
	method := c.Request.Method
	// 放行所有OPTIONS方法
	if method == "OPTIONS" {
		c.AbortWithStatus(http.StatusNoContent)
        return // 直接退出当前请求
	}
	// 获取当前请求的origin; 地址形式: scheme://domain 如  "http://localhost:8000"  注意origin的最后是没有 / 斜杠的
	origin := c.GetHeader("Origin")
	// 如果请求origin在允许的origin之中,则直接将当前请求的origin设置为允许的origin
	if isAllowOrigin(origin) {
		c.Header("Access-Control-Allow-Origin", origin)
	} else {
		// 不在允许范围,将配置中的域名作为允许origin设置
		c.Header("Access-Control-Allow-Origin", viper.String("app.baseUrl"))
	}
	// 附带身份凭证的请求, 注意这里如果是true, 则 Access-Control-Allow-Origin 不允许使用 * 通配符
	c.Header("Access-Control-Allow-Credentials", "true")
	// 设定允许的请求方式
	c.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT,HEAD,PATCH")
	// 允许的请求头信息, 默认"Content-Type,X-CSRF-Token,Authorization,Token"
	c.Header("Access-Control-Allow-Headers", viper.String("security.corsAllowHeaders"))
	// 暴露头信息
	c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type, New-Token, New-Expires-At")
	// 处理请求
	c.Next()
}

// 检测当前origin是否是允许的origin
func isAllowOrigin(origin string) bool {
	// origin为空时 非跨域请求,直接放行
	if origin == "" {
		return true
	}
	corsAllowOrigins := viper.GetStringSlice("security.corsAllowOrigins")
	for _, v := range corsAllowOrigins {
		if v == origin || strutils.IsWmMatchingReg(origin, v) {
			return true
		}
	}
	return false
}

gin自定义中间件CORS使用示例

func main() {
	r := gin.New()
    
    // 使用自定义的CORS中间件
	r.Use(middleware.SecurityCORS)

	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"html": "<b>Hello, world!</b>",
		})
	})

	// 监听并在 0.0.0.0:8080 上启动服务
	r.Run(":8080")
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在gin框架中接收POST请求并在请求到达处理程序之前进行中间件处理,可以使用gin中间件功能。以下是一个示例中间件,它可以将POST请求请求体中的JSON解析为一个结构体,并将其绑定到请求的上下文中: ```go func JsonMiddleware() gin.HandlerFunc { return func(c *gin.Context) { if c.Request.Method == "POST" { var data interface{} err := c.BindJSON(&data) if err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.Set("json_data", data) } c.Next() } } ``` 在这个中间件中,我们首先检查请求的HTTP方法是否为POST。如果是,我们尝试将请求体中的JSON解析为一个结构体。如果解析失败,我们返回一个HTTP 400错误响应,并终止请求。否则,我们将解析后的数据绑定到请求上下文的“json_data”键中,并继续处理请求。 要在gin应用程序中使用这个中间件,我们只需要在路由注册之前将其添加到应用程序的中间件链中: ```go router := gin.Default() router.Use(JsonMiddleware()) router.POST("/my-endpoint", func(c *gin.Context) { data := c.MustGet("json_data") // 处理请求数据 }) ``` 在这个示例中,我们使用gin.Default()创建一个新的路由器实例,并使用JsonMiddleware()函数添加一个中间件到路由器的中间件链中。然后,我们注册一个POST处理程序,该处理程序使用c.MustGet("json_data")从请求上下文中获取JSON解析后的数据,并对数据进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值