是否存在node.js的现有用户身份验证库?特别是,我正在寻找可以为用户(使用自定义后端auth DB)进行密码身份验证的东西,并将该用户与会话关联。
在我编写一个认证库之前,我想看看人们是否知道现有的库。在谷歌上找不到明显的东西。
-Shreyas
是否存在node.js的现有用户身份验证库?特别是,我正在寻找可以为用户(使用自定义后端auth DB)进行密码身份验证的东西,并将该用户与会话关联。
在我编写一个认证库之前,我想看看人们是否知道现有的库。在谷歌上找不到明显的东西。
-Shreyas
当前回答
使用mongo的简单示例,用于为ie Angular客户端提供用户认证的API
在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);
}
其他回答
如果你想要第三方/社交网络登录集成,也要看看每个auth。
我基本上也在找同样的东西。具体来说,我想要的是:
使用express.js,它包装了Connect的中间件功能 “基于表单的”身份验证 对哪些路由进行验证的粒度控制 用户/密码的数据库后端 使用会话
我最终所做的是创建自己的中间件函数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("/");
}
});
});
无论如何,这种方法主要被设计为灵活和简单。我相信有很多方法可以改善它。如果你有任何建议,我非常希望得到你的反馈。
编辑:这是一个简化的例子。在生产系统中,您绝对不希望以纯文本的形式存储和比较密码。正如一位评论者指出的那样,有一些库可以帮助管理密码安全。
下面是一个使用时间戳令牌的新身份验证库。令牌可以通过电子邮件或短信发送给用户,而不需要将它们存储在数据库中。它可以用于无密码身份验证或双因素身份验证。
https://github.com/vote539/easy-no-password
披露:我是这个库的开发者。
会话+ If
我想,您没有找到很多好的库的原因是,使用库进行身份验证在很大程度上是过度设计的。
你要找的只是一个会话绑定器:)一个会话:
if login and user == xxx and pwd == xxx
then store an authenticated=true into the session
if logout destroy session
这是它。
我不同意你认为connect-auth插件是正确的选择的结论。
我也使用连接,但我不使用连接认证的原因有两个:
IMHO打破了connect-auth非常强大且易于阅读的洋葱环架构。不去——我的观点:)。 你可以在这里找到一篇关于connect如何工作和洋葱圈想法的非常好的简短文章。 如果你——如前所述——只是想使用数据库或文件的基本或http登录。Connect-auth太大了。它更适合OAuth 1.0、OAuth 2.0等
使用connect进行非常简单的身份验证
(这是完整的。只是执行测试,但如果你想在生产中使用它,请确保使用https) (为了符合rest原则,你应该使用POST-Request而不是GET-Request 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);
NOTE
我在一年多前写了这个声明,目前没有活动节点项目。可能会有API-Changes in Express。如果我需要修改什么,请加上评论。
对身份验证的另一种理解是passdless,这是express的一个基于令牌的身份验证模块,它绕过了密码[1]的固有问题。它实现起来很快,不需要太多表单,并且为普通用户提供了更好的安全性(完全披露:我是作者)。
[1]:密码过时