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
相关产品推荐
相关产品推荐

