паспорт-місцевий з node-jwt-simple


87

Як я можу поєднати місцевий паспорт, щоб повернути маркер JWT при успішній автентифікації?

Я хочу використовувати node-jwt-simple і, дивлячись на паспорт.js, я не знаю, як це робити.

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

Чи можна повернути маркер при виклику done ()? Щось на зразок цього ... (просто псевдокод)

if(User.validCredentials(username, password)) {
  var token = jwt.encode({username: username}, tokenSecret);
  done(null, {token : token}); //is this possible?
}

Якщо ні, як я можу повернути маркер?

Відповіді:


123

Я зрозумів це!

Перш за все потрібно реалізувати правильну стратегію. У моєму випадку LocalStrategy, і вам потрібно надати свою логіку перевірки. Для прикладу, скористаємось тим, що вказано в паспорті-local.

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));

підтверджений зворотний дзвінок, який ви надаєте function(username, password, done), подбає про пошук вашого користувача та перевірку відповідності пароля (поза рамками питання та моєї відповіді)

Паспорт.js очікує декількох частин для його роботи, одна - повернення користувача в стратегію. Я намагався змінити цю частину коду, і це було неправильно. Зворотний дзвінок очікує, falseякщо перевірка не вдасться, а object(перевіреного користувача) - якщо ви успішно виконаєте.

Тепер .... як інтегрувати JWT?

У своєму маршруті входу вам доведеться обробити успішну автентифікацію або невдалу. І саме тут вам потрібно додати створення маркера JWT. Подобається так:

(не забудьте відключити сеанс, інакше вам доведеться реалізувати функції серіалізації та десеріалізації. І вони вам не потрібні, якщо ви не продовжуєте сеанс, а це не так, якщо ви використовуєте аутентифікацію на основі маркера)

З прикладів для місцевих паспортів: (з доданим маркером JWT)

// POST /login
//   This is an alternative implementation that uses a custom callback to
//   achieve the same functionality.
app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err) }
    if (!user) {
      return res.json(401, { error: 'message' });
    }

    //user has authenticated correctly thus we create a JWT token 
    var token = jwt.encode({ username: 'somedata'}, tokenSecret);
    res.json({ token : token });

  })(req, res, next);
});

І це все! Тепер, коли ви телефонуєте / вхід та ім'я користувача та пароль POST (які завжди повинні бути над SSL), перший фрагмент коду спробує знайти користувача на основі вказаного вами імені користувача, а потім перевірте, чи відповідає пароль (звичайно, вам потрібно буде змініть це відповідно до ваших потреб).

Після цього буде викликано ваш маршрут входу, і ви зможете подбати про повернення помилки або дійсного маркера.

Сподіваюся, це комусь допоможе. І якщо я зробив якісь помилки або щось забув, дайте мені знати.


3
Паспорти BasicStrategy або DigestStrategy два інші варіанти. Однак, схоже, немає великої різниці між базовою та локальною стратегіями, оскільки жодна з них не потребує сеансів для роботи - просто місцева служба просить URL-адреси перенаправлення (що робить її трохи менш зручною для API).
funseiki

1
Привіт @cgiacomi, не могли б ви навести приклад маршруту, який перевіряє маркер?
Метт Кім,

3
Гей @ matt-kim насправді я не зберігаю маркер, він тимчасовий. Я не знаю, найкращий спосіб чи ні, але це те, що я роблю: користувач автентифікується, і я генерую маркер і повертаю його клієнту. Токен зберігається в localStorage, якщо клієнт - це веб-сайт, або ви можете зберегти його в додатку iPhone / Android. Коли клієнт повинен зробити запит на ресурс, він надсилає збережений маркер у серверну систему. Паспорт обробляє маркер. Ось суть стратегії на пред'явника для обробки маркера gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 Сподіваюся, це допоможе! :)
cgiacomi

1
Привіт @cgiacomi! можливо, це очевидно, але чи можете ви описати, як ви відключаєте сеанси під час користувальницького зворотного виклику?
MrMuh

2
@MrMuh оформити посилання gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 в моєму коментарі Я показую, як відключити сеанси: паспорт.аутентифікація ('носій', {сесія: false})
cgiacomi

18

Це чудове рішення, я просто хочу додати таке:

var expressJwt = require('express-jwt');

app.use('/api', expressJwt({secret: secret}));

Я люблю використовувати "express-jwt" для перевірки маркера.

До речі: у цій статті чудово дізнатися, як обробляти маркер на стороні клієнта за допомогою Angular, щоб відправити його назад із кожним запитом

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/


2
Я використовував лише express-jwtавтентифікацію, але читаючи документацію інших пакетів, таких як passport-jwt, я думаю, я буду дотримуватися express-jwt. Набагато простіший, набагато приємніший IMO
bobbyz

Просто FYI express-jwt не забезпечує підтримку токенів оновлення.
user3344977

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.