Библиотеки аутентификации пользователей для 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.
Ответ 10
Вот две популярные библиотеки Github для аутентификации node js:
https://github.com/jaredhanson/passport (предположительно)
https://nodejsmodules.org/pkg/everyauth
Ответ 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
Раскрытие информации: Я являюсь разработчиком этой библиотеки.