Chrome v.66下SSO登录遇ERR_UNSAFE_REDIRECT问题修复进展
我之前在Chrome 66版本里踩过类似的SSO登录坑,结合你描述的扩展登录流程,给你梳理下可能的问题点和实操性的修复思路:
先明确完整登录流程(补全你未写完的第4步)
- Chrome扩展打开新标签页,重定向到我方网站SSO页面,携带编码后的邮箱和完成URL作为查询参数
- SSO页面跳转至SSO服务器,用户完成授权操作
- SSO服务器携带令牌参数,重定向回我方网站
- 我方网站处理令牌后,同步登录状态回Chrome扩展,最终关闭SSO标签页完成登录
Chrome 66版本的特定问题根源
Chrome 66在隐私安全和扩展权限上做了不少收紧,这几个点最容易导致你的SSO流程卡壳:
- URL查询参数的编码/解码异常:该版本对特殊字符的URL处理逻辑有调整,若你的邮箱或完成URL包含@、/这类字符,单次编码可能导致参数在重定向中丢失或乱码
- 第三方Cookie限制升级:Chrome 66开始严格管控跨域Cookie的设置,SSO服务器重定向回我方网站时,可能无法正确写入或读取会话Cookie
- 扩展与网页的通信权限拦截:该版本更新了扩展内容脚本和后台的通信规则,若
manifest.json权限配置不全,我方网站无法和扩展同步登录状态 - 非用户触发的标签页操作被拦截:Chrome 66禁止无用户交互的标签页自动关闭,若流程里需要自动关闭SSO标签页,会被浏览器阻止
针对性修复方案
1. 双重编码确保参数安全传递
不要只用一次encodeURIComponent,对敏感参数做双重编码,避免重定向过程中被浏览器自动解码导致参数失效:
// 扩展后台生成SSO跳转URL时 const userEmail = "user@example.com"; const completePageUrl = chrome.runtime.getURL("login-complete.html"); // 双重编码参数 const encodedEmail = encodeURIComponent(encodeURIComponent(userEmail)); const encodedCompleteUrl = encodeURIComponent(encodeURIComponent(completePageUrl)); const ssoRedirectUrl = `https://your-website.com/sso?email=${encodedEmail}&redirect=${encodedCompleteUrl}`; // 打开新标签页 chrome.tabs.create({ url: ssoRedirectUrl });
在我方SSO页面和完成页面接收参数时,对应做双重解码:
// 我方网站页面接收参数 const searchParams = new URLSearchParams(window.location.search); const decodedEmail = decodeURIComponent(decodeURIComponent(searchParams.get("email"))); const decodedCompleteUrl = decodeURIComponent(decodeURIComponent(searchParams.get("redirect")));
2. 调整Cookie属性适配第三方限制
如果SSO服务器和我方网站属于不同域名,在SSO服务器重定向回我方网站时,给令牌Cookie加上SameSite=None; Secure属性(Chrome 66已支持该属性):
// SSO服务器返回的响应头 Set-Cookie: auth_token=xxx; Path=/; Domain=your-website.com; SameSite=None; Secure; HttpOnly
如果不想依赖Cookie,也可以直接在URL中传递令牌,我方网站接收到后立即写入第一方Cookie,绕开第三方Cookie限制。
3. 完善扩展权限配置
在manifest.json中明确添加我方网站和SSO服务器的访问权限,同时配置内容脚本监听我方网站的完成页面:
{ "manifest_version": 2, // Chrome 66对应manifest v2 "permissions": [ "tabs", "https://your-website.com/*", "https://your-sso-server.com/*" ], "content_scripts": [ { "matches": ["https://your-website.com/login-complete*"], "js": ["content-script.js"] } ] }
通过内容脚本实现我方网站和扩展后台的通信,避免直接在网页中调用Chrome扩展API:
// content-script.js window.addEventListener("load", () => { const token = new URLSearchParams(window.location.search).get("token"); // 给扩展后台发送登录完成消息 chrome.runtime.sendMessage( { action: "finishLogin", token: token }, (response) => { if (response.success) { // 延迟关闭标签页,避免被Chrome拦截 setTimeout(() => window.close(), 800); } } ); });
4. 避免非用户触发的标签页操作
Chrome 66不允许无用户交互的自动关闭标签页,所以要么在完成页面加一个“点击关闭”按钮,要么通过内容脚本延迟执行关闭操作(上面代码里的setTimeout就是这个作用),给浏览器足够的判定时间。
调试小技巧
开启Chrome开发者工具(F12),在Application标签页查看Cookie是否正确写入,Console标签页排查跨域或权限错误,这能帮你快速定位具体是流程哪一步出了问题。
内容的提问来源于stack exchange,提问作者Serdg D.
相关产品推荐
相关产品推荐

