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

Node.js多文件引入passport为何能识别Google Strategy配置

核心原因:Node.js 模块缓存机制

你误以为两个文件中引入的是不同的passport实例,实际上两次require("passport")拿到的是完全相同的单例对象,这是Node.js CommonJS 模块规范的默认加载规则决定的:

  • Node.js 首次加载某个模块(包括npm安装的第三方包)时,会执行模块全部代码,将最终导出的结果存入内存缓存
  • 后续在项目任意文件中再次require同一个模块时,Node.js不会重新执行模块代码,直接返回内存中缓存的导出结果
  • passport包本身导出的就是预先实例化好的全局认证对象,而非可实例化的类,不存在每次引入都新建实例的逻辑

对应你的代码执行流程

  1. 入口文件index.js最先执行require("./services/passport"):
    • 首先加载passport包,将导出的passport单例存入缓存
    • 执行你写的配置逻辑,调用passport.use()把初始化好的Google Strategy(包含clientID、clientSecret、callbackURL等全部配置)注册到passport内部的策略映射表中,该策略默认的名称就是google
  2. 后续加载authRoutes.js时,文件内的const passport = require("passport")直接从缓存中拿到已经完成Google策略注册的同一个passport对象
  3. 当路由中调用passport.authenticate("google")时,passport会从内部维护的策略映射表中,找到之前注册好的名为google的策略实例,自然可以读取到所有配置参数完成认证逻辑

验证方式

你可以自行做个小测试验证单例特性:
在services/passport.js中给passport对象加一个自定义属性:

// services/passport.js
const passport = require("passport");
passport._customFlag = "配置文件设置的自定义标记";
// 剩下的原有Google策略配置代码不变

在authRoutes.js中打印这个属性:

// authRoutes.js
const passport = require("passport");
console.log(passport._customFlag); 
// 运行后会正常输出「配置文件设置的自定义标记」,证明两个文件拿到的是同一个对象

相关代码参考

Index.js

const express = require("express");
require("./services/passport");


const app = express();

require("./routes/authRoutes")(app);

app.listen(5000);

services文件夹下的passport.js

const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const keys = require("../config/keys");

passport.use(
  new GoogleStrategy(
    {
      clientID: keys.googleClientID,
      clientSecret: keys.googleClientSecret,
      callbackURL: "/auth/google/callback",
    },
    (accessToken, refreshToken, profile, done) => {
      console.log("accessToken", accessToken);
      console.log("refreshToken", refreshToken);
      console.log("profile", profile);
      console.log("done", done);
    }
  )
);

authRoute.js

const passport = require("passport");
// 此处引入的passport和配置文件中是同一个实例,因此可以读取到已注册的Google策略配置

module.exports = (app) => {

  app.get(
    "/auth/google",
    passport.authenticate("google", {
      scope: ["profile", "email"],
    })
  );

  app.get("/auth/google/callback", passport.authenticate("google"));
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:06:23