我最近在写一个管理系统的后端项目,用的是 Go,使用了 gin
来写服务器。跟前端本地联调的时候一直是没问题的,但直到有一天前后端部署到了 Test 环境开始测试,发现所有的 GET 请求都没问题,但所有的 POST 和 PUT 请求都 403 了。
我再三检查了一下 Request Authorizor Middleware,确认了并没问题(不然前端本地访问也不会正常),而且如果确实因为权限问题而 403,是有错误信息的,但现在没有任何信息。于是我连上服务器开始看 Log,发现无论是 gin
的 Access Log 还是 Error Log,都没有关于 POST 和 PUT 的访问记录,说明很有可能请求都没能坚持到这儿。
后来与同事一起找原因,同事使用 Postman 手动发了个请求,成功了,于是我也用 Postman 抓了个包发出去,但还是 403,整个 src
中返回 http.StatusBadRequest
的地方只有 Request Authorizor Middleware 一处……
实在找不到问题,于是我将 Request Header 一个个删掉再发送,直到删掉了 Origin 字段,发现可以了……
于是就注意到了 gin-cors
这个包。我们这个后端项目需要接受从 http://localhost:3000
传来的跨域请求,以方便前端调试。要支持跨域的话,首选 gin-cors
。按照官方文档的说法,写起来应该很简单:
import "github.com/itsjamie/gin-cors"
// Initialize a new Gin router
router := gin.New()
// Apply the middleware to the router (works with groups too)
router.Use(cors.Middleware(cors.Config{
Origins: "http://localhost:3000",
Methods: "GET, PUT, POST, DELETE",
RequestHeaders: "Origin, Authorization, Content-Type",
// ....
}))
然后我在想,如果 gin-cors
足够智障,不管是否跨域,只要看到 Header 中有 Origin 字段,就从设置的 Origins 中判断,如果没通过就 403,就会出现这样的问题。于是我将 Test 环境的域名加到了 Origins,部署,可以了……
至于为什么连 Access Log 都没有,因为记录 Log 的代码在 gin-cors
的后面……