локальный паспорт с 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, и вам необходимо предоставить свою логику проверки. Например, для саке воспользуемся тем, что указано в местном паспорте.

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), позаботится о поиске вашего пользователя и проверке совпадения пароля (выходит за рамки вопроса и моего ответа)

Passport.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. Однако, похоже, нет большой разницы между базовыми и локальными стратегиями, поскольку ни одна из них не требует сеансов для работы - просто Local запрашивает URL-адреса перенаправления (что делает его немного менее дружественным к API).
funseiki

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

3
Привет, @ matt-kim, на самом деле я не сохраняю токен, он временный. Я не знаю, лучший это способ или нет, но вот что я делаю: пользователь аутентифицируется, я генерирую токен и возвращаю его клиенту. Токен хранится в localStorage, если клиент является веб-сайтом, или вы можете сохранить его в приложении для iPhone / Android. Когда клиенту необходимо сделать запрос на ресурс, он отправляет сохраненный токен в бэкэнд. Паспорт будет обрабатывать жетон. Вот суть стратегии Bearer для обработки токена gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 Надеюсь, это поможет! :)
cgiacomi 05

1
Привет, @cgiacomi! возможно, это очевидно, но не могли бы вы описать, как отключить сеансы при использовании настраиваемого обратного вызова?
MrMuh

2
@MrMuh проверьте ссылку gist.github.com/cgiacomi/cd1efa187b8cccbe2a61 в моем комментарии. Я показываю, как отключить сеансы: паспорт.authenticate ('bearer', {session: 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. Гораздо проще, намного приятнее ИМО
bobbyz

Просто FYI express-jwt не поддерживает токены обновления.
user3344977

3

Вот шаблон, над которым я работаю, специально для использования только токенов api (нет сеансов ... не этот сеанс, конечно, плох; просто мы используем подход с использованием токенов): https://github.com/roblevintennis/passport -api-токены

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.