Passport.js : Войдите в систему с помощью Github и верните адрес электронной почты

#javascript #node.js #express #passport.js

#javascript #node.js #экспресс #passport.js

Вопрос:

Я создал node.js веб-приложение, которое используется passport.js вместе со passport-github стратегией. Вот мой код:

 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 для адреса электронной почты. Мой первый вопрос: есть ли способ гарантировать, что я всегда буду получать адрес электронной почты? И мой второй вопрос: если нет, то как мне сохранить это в базе данных без адреса электронной почты? Возможно, назначив мое собственное поле идентификатора пользователя и используя их идентификатор Github? Всегда ли идентификатор GitHub будет уникальным?

Ответ №1:

Если вы используете passport-github стратегию:

Вы должны пройти scope: 'user:email' , а не передавать profileFields: ['email'] , который передается в стратегии Facebook Passport.

Как сказал @mherzig, вам следует подумать о поиске области использования OAuth, которую вы используете, и Github принимает user:email для передачи электронных писем

Итак, вы должны использовать это для passport-github стратегии:

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

Источник


Если вы используете 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
},
...
);
  

Источник

Ответ №2:

Большинство служб аутентификации имеют концепцию областей действия — вы можете получить определенную личную информацию только в том случае, если пользователь согласен предоставить вам ее. Для GitHub см. https://developer.github.com/v3/oauth/#scopes .

В принципе, области, к которым вы хотите получить доступ, должны быть переданы вместе с запросом аутентификации. Я не уверен, как это происходит с passport-github, но, возможно, есть другой способ сделать это, который отправляет область, которую вы ищете.

Если вам действительно не нужен адрес электронной почты, и вы просто хотели, чтобы он был уникальным, тогда не запрашивайте его — пользователи увидят, какие области вы запрашиваете, и если вы запрашиваете слишком много, они могут отказаться от аутентификации вашего приложения. Идентификатор пользователя будет уникальным для GitHub, но может быть не уникальным для всех поставщиков удостоверений (если вы в конечном итоге используете не только GitHub), поэтому, если вам нужен уникальный идентификатор, вы должны каким-то образом объединить / хэшировать поставщика и идентификатор пользователя, чтобы он был уникальным для всех поставщиков.

Ответ №3:

Пользователи GitHub могут настроить в своем профиле GitHub (Личные настройки / Профиль) «Общедоступную электронную почту».

Если они не выбрали общедоступный адрес электронной почты, вы не получите никаких пользовательских сообщений электронной почты от GitHub.

Идентификатор GitHub будет (вероятно) уникальным и постоянным. Но я предлагаю вам дважды проверить политики GitHub.