Passport.js:使用Github登录并返回电子邮件地址

时间:2016-10-04 21:03:45

标签: javascript node.js express passport.js

我构建了一个使用passport.js策略的passport-github的node.js网络应用。这是我的代码:

var express = require('express');
var app = express();
app.use(express.static('public'));
var passport = require('passport');
var GithubStrategy = require('passport-github').Strategy;
passport.use(new GithubStrategy({
    clientID: "foo",
    clientSecret: "bar",
    callbackURL: "baz",
    profileFields: ['email']
}, function(accessToken, refreshToken, profile, done) {
    return done(null, profile);
}));
passport.serializeUser(function(user, done) {
    done(null, user);
});
passport.deserializeUser(function(user, done) {
    done(null, user);
});
app.use(session({
    secret: 'this is a secret',
    resave: false,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
    html = JSON.stringify(req.user, null, 4);
    res.render('index', {
        title: 'My Home Page',
        html: html
    });
});
//Login
app.get('/login', function(req, res) {
    res.render('login', {
        title: 'Login to Chordscribble!'
    });
});
//Logout
app.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/');
});
// GitHub
app.get('/auth/github', passport.authenticate('github', {
    scope: ['user:email']
}));
app.get('/auth/github/callback', passport.authenticate('github', {
    failureRedirect: '/login'
}), function(req, res) {
    res.redirect('/');
});
app.listen(3000);

一切正常,但我的电子邮件地址的返回值为null。我的第一个问题是,有没有办法保证我总能得到一个电子邮件地址?而且,我的第二个问题是,如果没有,我应该如何将其存储在没有电子邮件地址的数据库中?可能通过分配我自己的用户ID字段并使用他们的Github ID? GitHub ID总是独一无二的吗?

3 个答案:

答案 0 :(得分:2)

如果您使用的是passport-github策略:

您应该传递scope: 'user:email',而不是传递Facebook Passport策略中传递的profileFields: ['email']

正如@mherzig所说,你应该考虑寻找你正在使用的OAuth scope,并且Github接受user:email传递电子邮件

因此,您应该将此用于passport-github策略:

  new GitHubStrategy(
    {
      clientID: ...,
      clientSecret: ...,
      callbackURL: ...,
      scope: 'user:email',
    },
    ...
  );

Source

如果您使用的是passport-github2策略:

您应该在github-passport2策略中将范围作为数组传递。

passport.use(new GitHubStrategy({
   clientID: process.env.GITHUB_CLIENT_ID,
   clientSecret: process.env.GITHUB_CLIENT_SECRET,
   scope: ['user:email'],
   callbackURL: process.env.GITHUB_CALLBACK_URL
},
...
);

Source

答案 1 :(得分:0)

大多数身份验证服务都具有范围的概念 - 如果用户同意让您拥有该范围,则只能获取某些个人信息。对于GitHub,请参阅https://developer.github.com/v3/oauth/#scopes

基本上,您要访问的范围必须与身份验证请求一起传递。我不确定如何使用passport-github,但也许有另一种方法可以发送你正在寻找的范围。

如果你真的不需要电子邮件地址并且你只是想要它的唯一性,那就不要求它 - 用户会看到你要求的范围,如果你要求太多,他们可能会选择不让您的应用进行身份验证。用户ID在GitHub中是唯一的,但在所有身份提供者中可能不是唯一的(如果你最终使用的不仅仅是GitHub),那么如果你需要一个唯一的ID,你应该以某种方式组合/哈希提供者用户ID,因此它在所有提供商中都是唯一的。

答案 2 :(得分:0)

GitHub用户可以在他们的GitHub个人资料(个人设置/个人资料)中配置“公共电子邮件”。

如果他们没有选择公共电子邮件地址,您将不会收到来自GitHub的任何用户电子邮件。

GitHub ID(可能)是唯一且永久的。但我建议你仔细检查GitHub政策。