vTiger 7.0集成socket.io时受csrf-magic.js影响触发CORS问题求助
问题根因
- socket.io 3.x及以上版本的握手请求为独立处理逻辑,默认不会继承你配置的express CORS中间件规则,导致预检请求没有返回正确的CORS响应头
- 当前express中间件没有显式处理OPTIONS类型的预检请求,部分浏览器的预检请求会直接判定失败
- CORS配置中未加入csrf-magic生成的自定义请求头字段,导致请求被拦截
解决步骤
1. 调整socket.io初始化配置,单独配置CORS规则
将原代码中socket.io初始化部分修改为如下内容,直接在socket.io层面配置跨域规则:
const io = require("socket.io")(server, { cors: { origin: ["https://node.example.com", "https://vtiger.example.com"], methods: ["GET", "POST"], // 此处X-CSRF-Token可替换为你实际使用的csrf请求头字段名 allowedHeaders: ["Content-Type", "Authorization", "X-CSRF-Token"], credentials: true } });
2. 调整express中间件顺序,补充预检请求处理
将express的CORS中间件移动到socket.io初始化之前,同时增加OPTIONS请求的直接返回逻辑:
const app = require("express")(); // 优先配置CORS中间件 app.use(function (req, res, next) { var allowedOrigins = [ "https://node.example.com", "https://vtiger.example.com" ]; var origin = req.headers.origin; if (allowedOrigins.indexOf(origin) > -1) { res.setHeader("Access-Control-Allow-Origin", origin); } res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); // 同样补充csrf头字段 res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, "X-CSRF-Token"); res.header("Access-Control-Allow-Credentials", true); // 直接返回OPTIONS预检请求 if (req.method === "OPTIONS") { return res.sendStatus(200); } return next(); }); // 再初始化服务和socket.io const server = require("https").Server(options, app); // 此处使用上一步给出的带CORS配置的socket.io初始化代码 const io = require("socket.io")(server, {/* 上述CORS配置 */});
3. 调整客户端连接代码,携带csrf请求头
客户端连接socket服务时,主动携带csrf-magic生成的token到请求头中:
// 可查看csrf-magic.js的全局导出变量替换实际的token取值方式,通常为csrfMagicToken const csrfToken = window.csrfMagicToken; var socket = io.connect('https://node.example.com:3010', { withCredentials: true, extraHeaders: { "X-CSRF-Token": csrfToken } });
验证
修改完成后重启node服务,清除浏览器缓存后重新访问vTiger页面即可正常建立socket连接。
内容的提问来源于stack exchange,提问作者Bradley Armstrong
相关产品推荐
相关产品推荐

