是否存在node.js的现有用户身份验证库?特别是,我正在寻找可以为用户(使用自定义后端auth DB)进行密码身份验证的东西,并将该用户与会话关联。
在我编写一个认证库之前,我想看看人们是否知道现有的库。在谷歌上找不到明显的东西。
-Shreyas
是否存在node.js的现有用户身份验证库?特别是,我正在寻找可以为用户(使用自定义后端auth DB)进行密码身份验证的东西,并将该用户与会话关联。
在我编写一个认证库之前,我想看看人们是否知道现有的库。在谷歌上找不到明显的东西。
-Shreyas
当前回答
下面是我的一个项目中的一些基本身份验证代码。我使用它来对付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;
}
};
其他回答
下面是我的一个项目中的一些基本身份验证代码。我使用它来对付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;
}
};
对身份验证的另一种理解是passdless,这是express的一个基于令牌的身份验证模块,它绕过了密码[1]的固有问题。它实现起来很快,不需要太多表单,并且为普通用户提供了更好的安全性(完全披露:我是作者)。
[1]:密码过时
看起来连接中间件的连接认证插件正是我所需要的
我使用的是express [http://expressjs.com],所以连接插件非常适合,因为express是连接的子类(好吧-原型)
关于手摇方法,要注意一点:
我很失望地看到,本文中建议的一些代码示例并不能防止会话固定或定时攻击等基本身份验证漏洞。
与这里的一些建议相反,身份验证并不简单,处理解决方案也不总是简单的。我推荐passsportjs和bcrypt。
但是,如果你决定着手解决问题,可以看看express js提供的例子,以获得灵感。
祝你好运。
使用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);
}