библиотеки аутентификации пользователя для node.js? - PullRequest
271 голосов
/ 17 августа 2010

Существуют ли какие-либо библиотеки аутентификации пользователя для node.js? В частности, я ищу что-то, что может выполнить аутентификацию по паролю для пользователя (с использованием пользовательской базы данных с аутентификацией внутреннего интерфейса) и связать этого пользователя с сеансом.

Прежде чем я написал библиотеку аутентификации, я подумал, что я посмотрю, знают ли люди о существующих библиотеках. Не удалось найти ничего очевидного через поиск в Google.

-Shreyas

Ответы [ 12 ]

231 голосов
/ 24 октября 2011

Если вы ищете среду аутентификации для Connect или Express, стоит изучить Passport: https://github.com/jaredhanson/passport

(Раскрытие информации: я разработчик Passport)

Я разработал Passportпосле исследования как connect-auth, так и EveryAuth.Хотя они оба являются отличными модулями, они не удовлетворяли моим потребностям.Я хотел что-то более легкое и ненавязчивое.

Паспорт разбит на отдельные модули, поэтому вы можете использовать только то, что вам нужно (OAuth, только при необходимости).Паспорт также не монтирует какие-либо маршруты в вашем приложении, предоставляя вам возможность решать, когда и где вы хотите выполнить аутентификацию, и перехватывает управление тем, что происходит, когда аутентификация проходит успешно или не удается.

Например, вотпошаговый процесс настройки аутентификации на основе форм (имя пользователя и пароль):

passport.use(new LocalStrategy(
  function(username, password, done) {
    // Find the user from your DB (MongoDB, CouchDB, other...)
    User.findOne({ username: username, password: password }, function (err, user) {
      done(err, user);
    });
  }
));

app.post('/login', 
  passport.authenticate('local', { failureRedirect: '/login' }),
  function(req, res) {
    // Authentication successful. Redirect home.
    res.redirect('/');
  });

Для аутентификации доступны дополнительные стратегии через Facebook, Twitter и т. д. При необходимости можно подключить пользовательские стратегии.

89 голосов
/ 12 февраля 2011

Session + If

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

То, что вы ищете, это просто привязка сессии :) Сессия с:

if login and user == xxx and pwd == xxx 
   then store an authenticated=true into the session 
if logout destroy session

Вот и все.


Я не согласен с вашим выводом о том, что плагин connect-auth - это путь.

Я также использую connect , но я не использую connect-auth по двум причинам:

  1. ИМХО ломает connect-auth очень мощную и легкую для чтения архитектуру on-ring. А не ходи - моё мнение :). Вы можете найти очень хорошую и короткую статью о том, как работает connect, и об идее лукового кольца здесь .

  2. Если вы - как написано - просто хотите использовать простой или http логин с базой данных или файлом. Connect-auth слишком велик. Это больше для таких вещей, как OAuth 1.0, OAuth 2.0 и Co


Очень простая аутентификация с подключением

(Все готово. Просто запустите его для тестирования, но если вы хотите использовать его в работе, обязательно используйте https) (И чтобы быть REST-принцип-совместимым, вы должны использовать POST-запрос вместо GET-запроса, потому что вы меняете состояние:)

var connect = require('connect');
var urlparser = require('url');

var authCheck = function (req, res, next) {
    url = req.urlp = urlparser.parse(req.url, true);

    // ####
    // Logout
    if ( url.pathname == "/logout" ) {
      req.session.destroy();
    }

    // ####
    // Is User already validated?
    if (req.session && req.session.auth == true) {
      next(); // stop here and pass to the next onion ring of connect
      return;
    }

    // ########
    // Auth - Replace this example with your Database, Auth-File or other things
    // If Database, you need a Async callback...
    if ( url.pathname == "/login" && 
         url.query.name == "max" && 
         url.query.pwd == "herewego"  ) {
      req.session.auth = true;
      next();
      return;
    }

    // ####
    // This user is not authorized. Stop talking to him.
    res.writeHead(403);
    res.end('Sorry you are not authorized.\n\nFor a login use: /login?name=max&pwd=herewego');
    return;
}

var helloWorldContent = function (req, res, next) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('authorized. Walk around :) or use /logout to leave\n\nYou are currently at '+req.urlp.pathname);
}

var server = connect.createServer(
      connect.logger({ format: ':method :url' }),
      connect.cookieParser(),
      connect.session({ secret: 'foobar' }),
      connect.bodyParser(),
      authCheck,
      helloWorldContent
);

server.listen(3000);

Примечание

Я написал это заявление более года назад, и в настоящее время у меня нет активных узловых проектов. Так что в Express могут быть изменения API. Пожалуйста, добавьте комментарий, если я должен что-то изменить.

26 голосов
/ 22 августа 2010

Похоже, что плагин connect-auth для промежуточного программного обеспечения подключения - это именно то, что мне нужно: http://wiki.github.com/ciaranj/connect-auth/creating-a-form-based-strategy

Я использую экспресс [http://expressjs.com], поэтому подключаемый модуль очень хорошо вписывается, так как экспресс находится в подклассе (хорошо - прототип) из connect

14 голосов
/ 27 марта 2012

Я в основном искал то же самое. В частности, я хотел следующее:

  1. Чтобы использовать express.js, который включает в себя возможности промежуточного программного обеспечения Connect
  2. Проверка подлинности на основе форм
  3. Детальный контроль над тем, какие маршруты аутентифицированы
  4. База данных для пользователей / паролей
  5. Использование сессий

Я закончил тем, что создал свою собственную функцию промежуточного программного обеспечения check_auth, которую я передаю в качестве аргумента каждому маршруту, который я хочу аутентифицировать. check_auth просто проверяет сеанс и, если пользователь не вошел в систему, затем перенаправляет его на страницу входа, например:

function check_auth(req, res, next) {

  //  if the user isn't logged in, redirect them to a login page
  if(!req.session.login) {
    res.redirect("/login");
    return; // the buck stops here... we do not call next(), because
            // we don't want to proceed; instead we want to show a login page
  }

  //  the user is logged in, so call next()
  next();
}

Затем для каждого маршрута я гарантирую, что эта функция передается как промежуточное ПО. Например:

app.get('/tasks', check_auth, function(req, res) {
    // snip
});

Наконец, нам нужно обработать процесс входа в систему. Это просто:

app.get('/login', function(req, res) {
  res.render("login", {layout:false});
});

app.post('/login', function(req, res) {

  // here, I'm using mongoose.js to search for the user in mongodb
  var user_query = UserModel.findOne({email:req.body.email}, function(err, user){
    if(err) {
      res.render("login", {layout:false, locals:{ error:err } });
      return;
    }

    if(!user || user.password != req.body.password) {
      res.render("login",
        {layout:false,
          locals:{ error:"Invalid login!", email:req.body.email }
        }
      );
    } else {
      // successful login; store the session info
      req.session.login = req.body.email;
      res.redirect("/");
    }
  });
});

Во всяком случае, этот подход был в основном разработан, чтобы быть гибким и простым. Я уверен, что есть множество способов улучшить это. Если у вас есть, я бы очень хотел получить ваши отзывы.

РЕДАКТИРОВАТЬ: Это упрощенный пример. В производственной системе вы никогда не захотите хранить и сравнивать пароли в виде простого текста. Как указывает комментатор, есть библиотеки, которые могут помочь в управлении паролем.

13 голосов
/ 08 сентября 2011

Также посмотрите на Everyauth , если вы хотите, чтобы интеграция сторонних / социальных сетей.

7 голосов
/ 18 августа 2010

Вот код для базовой аутентификации из одного из моих проектов. Я использую его против CouchDB с дополнительным кэшем данных аутентификации, но я удалил этот код.

Оберните метод аутентификации вокруг вашей обработки запроса и предоставьте второй обратный вызов для неудачной аутентификации. Обратный вызов успеха получит имя пользователя в качестве дополнительного параметра. Не забудьте правильно обрабатывать запросы с неправильными или отсутствующими учетными данными при сбое обратного вызова:

/**
 * Authenticate a request against this authentication instance.
 * 
 * @param request
 * @param failureCallback
 * @param successCallback
 * @return
 */
Auth.prototype.authenticate = function(request, failureCallback, successCallback)
{
    var requestUsername = "";
    var requestPassword = "";
    if (!request.headers['authorization'])
    {
        failureCallback();
    }
    else
    {
        var auth = this._decodeBase64(request.headers['authorization']);
        if (auth)
        {
            requestUsername = auth.username;
            requestPassword = auth.password;
        }
        else
        {
            failureCallback();
        }
    }


    //TODO: Query your database (don't forget to do so async)


    db.query( function(result)
    {
        if (result.username == requestUsername && result.password == requestPassword)
        {
            successCallback(requestUsername);
        }
        else
        {
            failureCallback();
        }
    });

};


/**
 * Internal method for extracting username and password out of a Basic
 * Authentication header field.
 * 
 * @param headerValue
 * @return
 */
Auth.prototype._decodeBase64 = function(headerValue)
{
    var value;
    if (value = headerValue.match("^Basic\\s([A-Za-z0-9+/=]+)$"))
    {
        var auth = (new Buffer(value[1] || "", "base64")).toString("ascii");
        return {
            username : auth.slice(0, auth.indexOf(':')),
            password : auth.slice(auth.indexOf(':') + 1, auth.length)
        };
    }
    else
    {
        return null;
    }

};
4 голосов
/ 29 июня 2014

Другой подход к аутентификации - это Passwordless, модуль аутентификации на основе токенов *1002* для экспресс, который обходит внутреннюю проблему паролей [1]. Это быстро реализуется, не требует слишком много форм и предлагает лучшую безопасность для среднего пользователя (полное раскрытие: я автор).

[1]: Устаревшие пароли

3 голосов
/ 03 февраля 2014

Прошло несколько лет, и я хотел бы представить свое решение для аутентификации для Express.Это называется Lockit .Вы можете найти проект на GitHub и короткое вступление на моем блоге .

Так чем же отличаются существующие решения?

  • прост в использовании: настроить вашу БД, установить npm, require('lockit'), lockit(app), выполнено
  • маршруты уже встроены (/ регистрация, / логин, / забыл-пароль и т. д.)
  • представления уже встроены (на основе Bootstrap, но вы можете легко использовать собственные представления)
  • поддерживает связь JSON для одностраничных приложений AngularJS / Ember.js
  • НЕ поддерживает OAuth и OpenID.Только username и password.
  • он работает с несколькими базами данных (CouchDB, MongoDB, SQL) из коробки
  • он имеет тесты (я не смог найти никаких тестов для гипсокартона)
  • активно поддерживается (по сравнению с каждым)
  • проверка электронной почты и обработка забытого пароля (отправка электронной почты с токеном, не поддерживается Passport)
  • модульность: использовать только то, чтовам нужна
  • гибкость: настраивайте все

Посмотрите на примеры .

2 голосов
/ 21 марта 2014

Вот две популярные библиотеки Github для аутентификации узла js:

https://github.com/jaredhanson/passport (предположительно)

https://nodejsmodules.org/pkg/everyauth

2 голосов
/ 09 ноября 2013

Существует проект под названием Гипсокартон , который реализует систему входа пользователя с Паспортом , а также имеет панель управления пользователями. Если вы ищете полнофункциональную систему аутентификации и управления пользователями, похожую на ту, что есть в Django, но для Node.js, то это она. Я обнаружил, что это действительно хорошая отправная точка для создания приложения для узла, для которого требовалась система аутентификации и управления пользователями. См. ответ Джареда Хансона для получения информации о том, как работает Паспорт.

...