代码之家  ›  专栏  ›  技术社区  ›  Stuart Brown

Google Passport策略中没有req.user

  •  0
  • Stuart Brown  · 技术社区  · 7 年前

    我遇到的问题是,用户可以使用Google策略创建一个帐户,但我无法完全获取该帐户,因此经过身份验证的用户(通过本地策略)可以简单地向其帐户添加额外的Google详细信息,以便他们可以使用本地策略或Google策略。

    在'index.js'中定义路由 const passportGoogle = require('../handlers/google'); 上面有我谷歌战略的细节。

    再往下 index.js authenticate authorise 路线:

    /* GOOGLE ROUTES FOR AUTHENTICATION*/
    
    router.get('/google',
        passportGoogle.authenticate('google', 
        { scope: ['profile', 'email'] }));
    
    router.get('/google/callback', 
        passportGoogle.authenticate('google', 
        {
            failureRedirect: '/',
            failureFlash: 'Failed Login!',
            successRedirect: '/account',
            successFlash: 'You are logged in!'
    
        }
    ));
    
    /* GOOGLE ROUTES FOR AUTHORISATION - IE A USER IS ALREADY LOGGED IN AND WANTS TO CONNECT THEIR GOOGLE ACCOUNT*/
    
    // send to google to do the authentication
    router.get('/connect/google', 
        passportGoogle.authorize('google', 
        { scope : ['profile', 'email'] }
    ));
    
    // the callback after google has authorized the user
    router.get('/connect/google/callback',
        passportGoogle.authorize('google', {
            successRedirect : '/profile',
            failureRedirect : '/'
        })
    );
    

    如上所述,我的谷歌战略定义如下 google.js

    var passport = require('passport');
    var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
    var User = require('../models/User');
    passport.use(new GoogleStrategy({
        clientID: process.env.GOOGLE_CLIENTID,
        clientSecret: process.env.GOOGLE_CLIENTSECRET,
        callbackURL: "http://127.0.0.1:7777/google/callback"
      },
      // google will send back the token and profile
    function(req, token, refreshToken, profile, done) {
    // console.log('here is res.locals.user'+ res.locals.user);
            console.log('here is req.user'+ req.user);
        // asynchronous
        process.nextTick(function() {
    
            // check if the user is already logged in
            if (!req.user) {
                console.log('THERE IS NO REQ.USR');
                // find the user in the database based on their facebook id
                User.findOne({ 'google.id': profile.id }, function(err, user) {
    
                    // if there is an error, stop everything and return that
                    // ie an error connecting to the database
                    if (err)
                        return done(err);
    
                    // if the user is found, then log them in
                    if (user) {
                        return done(null, user); // user found, return that user
                    } else {
                        // if there is no user found with that google id, create them
                        var newUser            = new User();
    
                        // set all of the facebook information in our user model
                        newUser.google.id = profile.id;
                        newUser.google.token = token;
                        newUser.name = profile.displayName;
                        newUser.email = profile.emails[0].value;
    
                        // save our user to the database
                        newUser.save(function(err) {
                            if (err)
                                throw err;
    
                            // if successful, return the new user
                            return done(null, newUser);
                        });
                    }
    
                });
    
            } else {
                const user = User.findOneAndUpdate(
                    { _id: req.user._id },
                    { $set: {"user.google.id":profile.id, 
                            "user.google.token":accessToken, 
                            "user.google.name":profile.displayName, 
                            "user.google.email":profile.emails[0].value
                        }
                    },   
                    { new: true, runValidators: true, context: 'query' }
                )
                .exec();
                return done(null, user);
                req.flash('success', 'Google details have been added to your account'); 
                res.redirect(`back`); 
            }
        });
    }));
    
    module.exports = passport;
    

    但是,当用户登录并遵循链接 /connect/google 总是创建一个新用户,而不是更新他们的详细信息。我的日志显示 if (!req.user) Google策略中的条件总是被触发,但我不确定为什么,因为用户肯定已经登录。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Andy Taton    7 年前

    为了访问回调中的req,您需要 passReqToCallback: true GoogleStrategy配置对象中的标志:

    passport.use(new GoogleStrategy({
        clientID: process.env.GOOGLE_CLIENTID,
        clientSecret: process.env.GOOGLE_CLIENTSECRET,
        callbackURL: "http://127.0.0.1:7777/google/callback",
        passReqToCallback: true
      },
      // google will send back the token and profile
    function(req, token, refreshToken, profile, done) {
    // console.log('here is res.locals.user'+ res.locals.user);
            console.log('here is req.user'+ req.user);
    ....
    })
    

    如果省略此标志,则预期的回调表单为

    function(accessToken, refreshToken, profile, done){...}
    

    所以你的代码正在寻找 user User.findOne({'google.id': profile.id}) 应该总是失败,因为函数是用 done 作为第四个论点而不是 profile

    推荐文章