后端服务CORS预检请求验证问题探究
问题探索
问题引入
目前在 Vite+Vue3 的项目中使用 fetch API 调用 siyuan 的 API 时候,如果加上 API 鉴权,就会返回 CORS 错误,如下:
根据 https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request 这篇文章的理解
在检测到 CORS 跨域复杂请求(例如 POST 等)时候,会发送一个 OPTIONS 的预检请求,请求会返回下一个请求允许的 header 和 method
检测请求可以看到
可以看到思源服务端返回的 Access-Control-Request-Headers 并没有 Authorization 字段。这就是导致最终 CORS 失败的根本原因。
最优解决方案
查看 https://github.com/siyuan-note/siyuan/blob/master/kernel/server/serve.go) 代码可以看到,服务端是支持 CORS 的,代码如下
1 | ginServer.Use(cors.Default()) |
这里实用的默认策略。我们看看详细的默认策略
可以看到并没有包含 Authorization 字段。
而 siyuan 的 API 文档鉴权部分明确表示需要在 header 传递该字段
https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md#%E9%89%B4%E6%9D%83
解决方案:
参考了
https://stackoverflow.com/questions/29418478/go-gin-framework-cors
代码修改如下
1 | func CORSMiddleware() gin.HandlerFunc { |
然后原来的
1 | ginServer.Use(cors.Default()) |
调整为
1 | ginServer.Use(CORSMiddleware()) |
问题解决。
候选的解决方案
如果修改内核影响太大或者看看能不能把跨域策略提供配置可选。
参考
https://blog.csdn.net/root_miss/article/details/82740399
https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
https://stackoverflow.com/questions/29418478/go-gin-framework-cors