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

Passport Google认证返回[Function: authenticate]而非谷歌登录页问题

问题描述

尝试使用Passport实现谷歌登录,配置文件与控制器代码如下,但调用passport.authenticate后输出======2======> [Function: authenticate],无法跳转到谷歌登录页面或获取用户profile信息。

1. Passport配置文件(Passport.js)

const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth2').Strategy;
const Config = require("../../configs/configs");

passport.serializeUser((user , done) => {
    done(null , user);
})
passport.deserializeUser(function(user, done) {
    done(null, user);
});

passport.use(new GoogleStrategy({
    clientID:Config.clientId, // Your Credentials here.
    clientSecret:Config.clientSecret, // Your Credentials here.
    callbackURL:"http://localhost:5041/auth/callback",
    passReqToCallback:true
  },
  function(request, accessToken, refreshToken, profile, done) {
    console.log(profile);
    return done(null, profile);
  }
));

module.exports = passport;

该文件已正确导出Passport实例。

2. 控制器相关函数

重定向函数

async registrationWithGoogle() {
    try {
      return this.res.send(`<?xml version='1.0'?> <!DOCTYPE html><html><head><title>HTML Meta Tag</title><meta http-equiv='refresh' content='3; url = ${Config.beRedirectUrlPrefix}${Config.serverPort}${Config.beRedirectUrlSuffix}?mode=${this.req.query.target}'/></head><body><p>Redirecting to another URL</p></body></html>`);
    } catch (error) {
      console.log(error);
      loggerError(
        this.req.url,
        this.req.method,
        this.req.connection.remoteAddress,
        this.req.body,
        this.req.params,
        0,
        error
      );
      this.res.send({ status: 0, message: error });
    }
  }

认证函数(对应/auth/redirect路由)

async validatePassportForGoogle() {
    try {
      const x = await passport.authenticate('google', { scope: [ 'email', 'profile' ] });
      console.log("======2======>", x);
    } catch (error) {
      console.log(error)
    }
  }
错误原因

passport.authenticate('google', ...)本身返回的是中间件函数,而非Promise。用await调用它只会拿到函数本身,无法触发认证流程,自然无法跳转谷歌登录页或获取用户信息。Passport认证中间件需要接入Express的请求响应周期,由Express调用它处理req/res对象。

修正方案

1. 调整认证函数写法

方式一:直接作为路由中间件(推荐)

将passport.authenticate直接绑定到路由,由Express自动处理:

const passport = require('./path/to/Passport.js');
const router = require('express').Router();

// 绑定/auth/redirect路由到谷歌认证中间件
router.get('/auth/redirect', passport.authenticate('google', { scope: ['email', 'profile'] }));

方式二:控制器内手动执行中间件

若必须在控制器函数内处理,手动传入req、res、next触发执行:

async validatePassportForGoogle() {
  try {
    // 手动调用认证中间件,传入当前请求上下文
    passport.authenticate('google', { scope: ['email', 'profile'] })(this.req, this.res, () => {});
  } catch (error) {
    console.log(error);
    loggerError(
      this.req.url,
      this.req.method,
      this.req.connection.remoteAddress,
      this.req.body,
      this.req.params,
      0,
      error
    );
    this.res.send({ status: 0, message: error });
  }
}

2. 配置回调路由处理认证结果

必须配置/auth/callback路由接收谷歌返回的认证信息:

router.get('/auth/callback', 
  passport.authenticate('google', { failureRedirect: '/login' }),
  (req, res) => {
    // 认证成功后的逻辑,比如跳转主页或返回用户信息
    res.redirect('/');
    // 或返回JSON:res.json(req.user);
  }
);

3. 确保Express应用初始化Passport会话

Passport依赖会话存储用户信息,需在Express应用中配置:

const express = require('express');
const session = require('express-session');
const passport = require('./path/to/Passport.js');
const app = express();

// 配置session
app.use(session({
  secret: 'your-custom-secret-key',
  resave: false,
  saveUninitialized: false
}));

// 初始化Passport及会话支持
app.use(passport.initialize());
app.use(passport.session());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:25:16