我刚刚完成了 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');
}
}]
});