Библиотеки аутентификации пользователей для node.js?

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

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

-Shreyas

Ответ 1

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

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

Ответ 2

Если вы ищете инфраструктуру проверки подлинности для Connect или Express, Passport заслуживает изучения: https://github.com/jaredhanson/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 и т.д. При необходимости могут быть подключены пользовательские стратегии.

Ответ 3

Сессия + Если

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

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

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

thats it.


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

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

  • IMHO разбивает connect-auth очень мощную и удобную для чтения кольцевую архитектуру соединения. Не-go - мое мнение:). Вы можете найти очень хорошую и короткую статью о том, как работают соединения и идея кольца лука здесь.

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


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

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

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);

Примечание

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

Ответ 4

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

  • Чтобы использовать express.js, который включает возможность подключения промежуточного программного обеспечения
  • Аутентификация на основе форм
  • Гранулированный контроль над проверкой маршрутов.
  • База данных для пользователей/паролей
  • Использовать сеансы

То, что я закончил, создало мою собственную функцию промежуточного программного обеспечения 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("/");
    }
  });
});

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

EDIT: Это упрощенный пример. В производственной системе вы никогда не захотите хранить и сравнивать пароли в виде обычного текста. Как отмечает комментатор, существуют библиотеки, которые могут помочь в управлении безопасностью паролей.

Ответ 5

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

Ответ 6

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

};

Ответ 7

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

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

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

Взгляните на examples.

Ответ 8

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

[1]: Пароли устарели

Ответ 9

Существует проект под названием Drywall, который реализует систему входа пользователя с Passport, а также панель управления пользователями. Если вы ищете полнофункциональную систему аутентификации и управления пользователями, похожую на то, что Django имеет, но для Node.js, это он. Я нашел, что это хорошая отправная точка для создания приложения node, которое требует аутентификации пользователя и системы управления. См. Jared Hanson для получения информации о том, как работает Passport.

Ответ 11

Быстрый простой пример с использованием mongo для API, который предоставляет пользователю auth, т.е. Angular client

в app.js

var express = require('express');
var MongoStore = require('connect-mongo')(express);

// ...

app.use(express.cookieParser());
// obviously change db settings to suit
app.use(express.session({
    secret: 'blah1234',
    store: new MongoStore({
        db: 'dbname',
        host: 'localhost',
        port: 27017
    })
}));

app.use(app.router);

для вашего маршрута примерно так:

// (mongo connection stuff)

exports.login = function(req, res) {

    var email = req.body.email;
    // use bcrypt in production for password hashing
    var password = req.body.password;

    db.collection('users', function(err, collection) {
        collection.findOne({'email': email, 'password': password}, function(err, user) {
            if (err) {
                res.send(500);
            } else {
                if(user !== null) {
                    req.session.user = user;
                    res.send(200);
                } else {
                    res.send(401);
                }
            }
        });
    });
};

Затем в ваших маршрутах, для которых требуется авторизация, вы можете просто проверить сеанс пользователя:

if (!req.session.user) {
    res.send(403);
}

Ответ 12

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

https://github.com/vote539/easy-no-password

Раскрытие информации: Я являюсь разработчиком этой библиотеки.