我已经构建了一个 Web 应用程序,该应用程序具有一个后端快速服务器,该服务器通过护照处理 oauth 身份验证。
我现在正在尝试构建一个随附的浏览器扩展程序,它将通过快速服务器与 Web 应用程序共享会话。
我有一种方法似乎可行,实际上是在新窗口中打开网络应用程序的 oauth 流。从技术上讲,身份验证是通过 Web 应用程序完成的,但扩展最终能够从服务器获取身份验证状态,因此这“有效”。
const signIn= () => {
chrome.windows.create({
url: "http://localhost:3000/auth/google-ext",
});
};
我不喜欢这个解决方案的地方在于它最小化了扩展。
我尝试使用 chrome.identity.launchWebAuthFlow 执行以下操作并调用我将从 webapp 使用的相同 oauth 端点。
chrome.identity.launchWebAuthFlow(
{
url: "http://localhost:5000/auth/google-ext",
interactive: true,
},
(responseUrl) => {
fetchUser();
}
);
这将打开 oauth 登录页面,但在尝试登录后,我在扩展端收到此错误:
未经检查的 runtime.lastError:无法加载授权页面。
在我的服务器上,我得到了一个
TokenError:未经授权
以下是我的特快路线和护照策略:
注意:当使用 windows.create 方法时,我会为我的网络应用程序使用谷歌客户端 ID。对于 launchWebAuthFlow 方法,我使用我的 google 扩展客户端 ID(Web 应用程序和扩展都在同一个 google 项目下)。
// Extension specific routes
router.get(
"auth/google-ext",
passport.authenticate("google-ext", {
scope: ["profile", "email"],
})
);
router.get(
"auth/google-ext/callback",
passport.authenticate("google-ext", {
failureFlash: true,
}),
(req, res) => {
res.redirect("https://<app-id>.chromiumapp.org/");
}
);
// passport.js
passport.use(
"google-ext",
new GoogleStrategy(
{
clientID: googleExtensionClientID,
clientSecret: googleClientSecret,
callbackURL: "/auth/google-ext/callback",
proxy: true,
},
async (accessToken, refreshToken, profile, done) => {
const existingUser = await User.findOne({ googleId: profile.id });
if (existingUser) {
return done(null, existingUser);
}
const user = await new User({
name: profile.name,
email: profile.emails[0].value,
googleId: profile.id,
}).save();
done(null, user);
}
)
);
我一直试图弄清楚这一点,但一直无法弄清楚。我想要做的甚至可能吗?我有使用谷歌的 getAuthToken 吗?
编辑:
如果我将我的网络应用程序客户端 ID 用于护照策略,则 oauth 流程可以正常工作,并且我的 /auth/google-ext/callback 正在接收req.user
. 但是,会话似乎没有被保存在任何地方,即req.user
以空/未定义的形式检索结果的后续请求。
这是我的服务器index.js
const app = express();
app.use(
cors({ origin: "chrome-extension://<app-id>" })
);
app.use(express.json());
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [cookieKey],
})
);
app.use(passport.initialize());
app.use(passport.session());