2

我刚刚完成了 Thinkster MEAN Stack 教程,并希望将其改编为我自己的项目。我真的很想让用户用谷歌登录,所以我正在尝试使用 Passport 的谷歌策略。我已经用 npm 安装了 passport-google-oauth,我什至在可以正确验证的地方安装了它。

我被困在如何将经过身份验证的用户的 JWT 集成回 Angular 应用程序的其余部分。在下面的代码中,单击 Google 的“允许”后,我返回到我的本地主机应用程序,并在屏幕上看到我的 JWT 的 JSON。如何让 JWT 回到我的 Angular 身份验证服务以进入 localStorage?使用我的其他登录功能,我可以使用 .success() 回调;使用 Google,我的回调来自不同的域。我猜这一切的关键是让 Angular 应用程序处理 JSON,我只是不知道如何触发它。

非常感谢您提供的任何帮助!这是我的文件:

护照.js:

passport.use(new GoogleStrategy({
    clientID: configAuth.googleAuth.clientID,
    clientSecret: configAuth.googleAuth.clientSecret,
    callbackURL: configAuth.googleAuth.callbackURL,
    passReqToCallback: true
}, function (req, token, refreshToken, profile, done) {
    process.nextTick(function () {
        if (!req.user) {
            User.findOne({ 'google.id': profile.id }, function (err, user) {
                if (err) { return done(err); }
                if (user) {
                    return done(null, user);
                } else {
                    var newUser = new User();

                    newUser.google.id = profile.id;
                    newUser.google.token = token;
                    newUser.google.name = profile.displayName;
                    newUser.google.email = profile.emails[0].value;

                    newUser.save(function (err) {
                        if (err) { throw err; }
                        return done(null, newUser);
                    });
                }
            });
        } else {
            var user = req.user;
            user.google.id = profile.id;
            user.google.token = token;
            user.google.name = profile.displayName;
            user.google.email = profile.emails[0].value;

            user.save(function (err) {
                if (err) { throw err; }
                return done(null, user);
            });
        }

    });
}
));

index.js(快速路由器):

.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }
))
.get('/auth/google/callback', function (req, res, next) {
    passport.authenticate('google', function (err, user, info) {
        if (err) { return next(err); }

        if (user) {
            return res.json({token: user.generateJWT()});
        } else {
            return res.status(401).json(info);
        }
    })(req, res, next);
})

angularApp.js auth 服务(localStrategy 登录的处理方式,供参考):

auth.saveToken = function (token) {
        $window.localStorage['outside-in-token'] = token;
    };
auth.login = function (user) {
    return $http.post('/login', user).success(function (data) {
        auth.saveToken(data.token);
    });
};

以及处理到 /login 的帖子的 index.js 路由器:

.post('/login', function (req, res, next) {
    if (!req.body.username || !req.body.password) {
        return res.status(400).json({ message: 'Please fill out all fields' });
    }

    passport.authenticate('local', function (err, user, info) {
        if (err) { return next(err); }

        if (user) {
            return res.json({token: user.generateJWT()});
        } else {
            return res.status(401).json(info);
        }
    })(req, res, next);
})

编辑 我想我可能已经找到了解决方案。我有一个 Google 回调将令牌作为查询字符串发送回我的登录页面。然后,在login我设置的状态下,我正在检查 enter if 是否$location.search().token已定义;如果是这样,我正在使用我的auth服务以这种方式将令牌保存到 localStorage 中。我可能可以通过一些额外的步骤来提高可靠性,但我认为这适用于现在。这仍然安全吗?我相信应该是这样,因为用户可以按原样进入 localStorage,但我想确保他们不能欺骗它或任何东西。

新的 index.js 路由器:

.get('/auth/google/callback', function (req, res, next) {
    passport.authenticate('google', function (err, user, info) {
        if (err) { return next(err); }

        if (user) {
            res.writeHead(302, {
                'Location': 'http://localhost:3000/#/login?token=' + user.generateJWT()
            });
            res.end();
        } else {
            return res.status(401).json(info);
        }
    })(req, res, next);
})

来自 angularApp.js 的 ui-router $state:

.state('login', {
            url: '/login',
            templateUrl: '/login.html',
            controller: 'AuthCtrl',
            onEnter: ['$state', 'auth', '$location', function ($state, auth, $location) {
                if ($location.search().token) {
                    auth.saveToken($location.search().token);
                }
                if (auth.isLoggedIn()) {
                    $state.go('home');
                }
            }]
        });
4

0 回答 0