You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从NodeJS重定向Chrome MV3扩展标签页失败,Passport.JS认证报错求助

Chrome Manifest V3扩展Passport.js谷歌认证JWT传递问题解决

问题场景

开发Chrome MV3扩展时,使用Passport.js实现谷歌OAuth用户认证,需要将JWT令牌传递到扩展前端。后端尝试通过重定向到chrome-extension://${EXTENSION_KEY}/tabs/auth.html?token=${token}来传递令牌,但出现跳转错误,添加web_accessible_resources配置后仍无效。

现有后端代码

app.get(
    ROUTES.AUTH_GOOGLE_CALLBACK,
    passport.authenticate("google", {
        failureRedirect: `${process.env.CLIENT_URI}/auth/sign-in?errorCode=500`,
    }),
    async (req: Request, res: Response) => {
        try {
            const user = req.user;
            const token = await signAccessToken(user);
            res.status(200).redirect(`chrome-extension://${EXTENSION_KEY}/tabs/auth.html?token=${token}`);
        } catch (error) {
            console.error("ERROR IN GOOGLE OAUTH HANDLER::", error);
            res.status(500).json({ error });
        }
    },
);

现有Manifest配置

"web_accessible_resources": [
    {
        "resources": [
            "tabs/auth.html"
        ],
        "matches": [
            "chrome-extension://<extension key>/*"
        ]
    }
],

问题分析

  1. web_accessible_resources配置错误:该字段用于控制外部网站(非扩展自身)可访问的扩展资源,配置chrome-extension://<extension key>/*完全无效,因为扩展内部资源默认无需额外权限即可访问。
  2. 跨协议跳转安全限制:浏览器对从HTTP/HTTPS协议直接跳转到chrome-extension://协议有严格安全限制,直接重定向会被拦截,导致页面无法正常加载。

解决方案

方案一:后端中转页面+消息传递(推荐)

通过后端中转页面过渡,再利用Chrome扩展的消息机制传递令牌,避免跨协议跳转限制。

1. 修改后端回调逻辑

将重定向目标改为后端域名下的中转页面,携带令牌参数:

app.get(
    ROUTES.AUTH_GOOGLE_CALLBACK,
    passport.authenticate("google", {
        failureRedirect: `${process.env.CLIENT_URI}/auth/sign-in?errorCode=500`,
    }),
    async (req: Request, res: Response) => {
        try {
            const user = req.user;
            const token = await signAccessToken(user);
            // 重定向到后端中转页面
            res.status(200).redirect(`/auth/extension-callback?token=${token}`);
        } catch (error) {
            console.error("ERROR IN GOOGLE OAUTH HANDLER::", error);
            res.status(500).json({ error });
        }
    },
);

2. 创建后端中转页面

在后端静态资源目录下创建extension-callback.html,通过chrome.runtime.sendMessage将令牌传递给扩展:

<!DOCTYPE html>
<html>
<body>
<script>
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('token');
const EXTENSION_ID = '<你的扩展实际ID>';

// 向扩展发送令牌
chrome.runtime.sendMessage(EXTENSION_ID, { type: 'RECEIVE_AUTH_TOKEN', token }, (response) => {
    if (response?.success) {
        // 令牌传递成功,跳转到扩展的auth页面
        window.location.href = `chrome-extension://${EXTENSION_ID}/tabs/auth.html`;
    } else {
        alert('扩展未安装,请先安装后重试');
        window.location.href = '/auth/sign-in';
    }
});
</script>
</body>
</html>

3. 扩展中监听消息

在扩展的背景脚本(background.js)中添加消息监听,接收令牌并存储:

chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
    if (message.type === 'RECEIVE_AUTH_TOKEN' && message.token) {
        // 将令牌存储到chrome.storage.local
        chrome.storage.local.set({ authToken: message.token }, () => {
            sendResponse({ success: true });
        });
        return true; // 标记异步响应
    }
});

方案二:修正web_accessible_resources(仅适用于特殊场景)

如果必须直接访问扩展资源,修正web_accessible_resources配置,将matches设置为后端域名(允许后端页面访问扩展资源):

"web_accessible_resources": [
    {
        "resources": ["tabs/auth.html"],
        "matches": ["https://<你的后端域名>/*"]
    }
],

但此方案仍可能面临跨协议跳转限制,不推荐作为首选。

注意事项

  • 确保EXTENSION_KEY/EXTENSION_ID为扩展的实际ID,开发环境可在chrome://extensions页面开启开发者模式后查看。
  • 令牌传递过程中注意安全,避免令牌泄露,可通过HTTPS传输、短时效令牌等方式强化安全。

内容的提问来源于stack exchange,提问作者Ankit Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:30:05