Chrome扩展调用Rally WSAPI v2.0时API Key授权异常求助
这个问题的核心是浏览器自动携带的SSO会话Cookie与你手动设置的API Key认证头发生冲突:当用户通过SSO登录Rally网站后,浏览器会在rally1.rallydev.com域名下存储一个ZSESSIONID Cookie;当你的扩展发起XHR请求时,浏览器默认会自动带上这个Cookie,而Rally服务器会优先识别Cookie中的会话ID,忽略你请求头里的API Key,导致认证失败出现"Invalid key"错误。
下面是几个可行的解决方案,按优先级排序:
1. 禁止XHR携带Cookie(最直接有效)
修改你的initXHR函数,添加withCredentials = false配置,强制浏览器不自动携带目标域名的Cookie,这样服务器就会优先读取你请求头中设置的API Key:
function initXHR(method, url, apikey, cbFunc) { let httpRequest = new XMLHttpRequest(); ... httpRequest.open(method, url); // 关键配置:阻止浏览器自动携带Cookie,避免冲突 httpRequest.withCredentials = false; httpRequest.setRequestHeader('Content-Type', 'application/json'); httpRequest.setRequestHeader('Accept', 'application/json'); httpRequest.setRequestHeader('ZSESSIONID', apikey); httpRequest.onreadystatechange = function() { ... }; return httpRequest; }
这个方法不需要修改认证逻辑,只是切断了Cookie的自动携带,完美解决SSO会话和API Key的冲突问题。
2. 改用标准Authorization头传递API Key(更规范)
部分API平台推荐使用Authorization头传递API Key,避免和Cookie中的ZSESSIONID重名冲突。你可以尝试将认证头替换为:
httpRequest.setRequestHeader('Authorization', `Bearer ${apikey}`);
去掉原来的ZSESSIONID头配置。不过需要先确认Rally WSAPI v2.0是否支持这种认证方式(大部分现代API都支持,但建议先做小范围测试)。
3. 切换到Fetch API(代码更简洁)
如果你的扩展不需要兼容老旧浏览器,推荐使用fetch API代替XMLHttpRequest。Fetch默认不会携带跨域Cookie(你的扩展背景页与Rally属于跨域),显式设置credentials: 'omit'可以彻底杜绝Cookie干扰:
async function createRallyWorkItem(baseURL, apikey, workItemData) { try { const response = await fetch(`${baseURL}/hierarchicalrequirement/create`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'ZSESSIONID': apikey }, credentials: 'omit', // 显式禁止携带任何Cookie body: JSON.stringify(workItemData) }); const result = await response.json(); // 处理返回结果 cbFunc(result); } catch (error) { // 处理错误 cbFunc(null, error); } }
额外注意点
- 不要依赖清除Cookie的临时方案,这会影响用户的网站使用体验,也不是可持续的解决办法。
- 如果你的扩展需要同时处理用户的SSO会话和API Key请求,建议将API请求放在独立的上下文(比如扩展的后台页)中,避免与前端页面的Cookie共享。
内容的提问来源于stack exchange,提问作者kino2814

