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

用于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博客

CoffeeScript 复制代码
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

Go 复制代码
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使用示例

Go 复制代码
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")
}
相关推荐
米丘5 分钟前
了解 Javascript 模块化,更好地掌握 Vite 、Webpack、Rollup 等打包工具
前端
Heo6 分钟前
深入 React19 Diff 算法
前端·javascript·面试
滕青山7 分钟前
个人所得税计算器 在线工具核心JS实现
前端·javascript·vue.js
小怪点点8 分钟前
手写promise
前端·promise
国思RDIF框架17 分钟前
RDIFramework.NET Web 敏捷开发框架 V6.3 发布 (.NET8+、Framework 双引擎)
前端
Mintopia18 分钟前
如何在有限的时间里,活出几倍的人生
前端
炫饭第一名19 分钟前
速通Canvas指北🦮——变形、渐变与阴影篇
前端·javascript·程序员
Neptune120 分钟前
让我带你迅速吃透React组件通信:从入门到精通(上篇)
前端·javascript
阿懂在掘金20 分钟前
Vue 表单避坑(一):为什么 v-model 绑定对象属性会偷偷修改父组件数据?
前端·vue.js
小码哥_常25 分钟前
Android与JS交互:解锁混合开发的魔法之门
前端