node.js 的用户身份验证库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3498005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
user authentication libraries for node.js?
提问by shreddd
Are there any existing user authentication libraries for node.js? In particular I'm looking for something that can do password authentication for a user (using a custom backend auth DB), and associate that user with a session.
node.js 是否有任何现有的用户身份验证库?特别是我正在寻找可以为用户进行密码身份验证的东西(使用自定义后端身份验证数据库),并将该用户与会话相关联。
Before I wrote an auth library, I figured I would see if folks knew of existing libraries. Couldn't find anything obvious via a google search.
在我写一个 auth 库之前,我想我会看看人们是否知道现有的库。通过谷歌搜索找不到任何明显的东西。
-Shreyas
-Shreyas
采纳答案by shreddd
Looks like the connect-auth plugin to the connect middleware is exactly what I need: http://wiki.github.com/ciaranj/connect-auth/creating-a-form-based-strategy
看起来连接中间件的 connect-auth 插件正是我所需要的:http: //wiki.github.com/ciaranj/connect-auth/creating-a-form-based-strategy
I'm using express [ http://expressjs.com] so the connect plugin fits in very nicely since express is subclassed (ok - prototyped) from connect
我正在使用 express [ http://expressjs.com],因此 connect 插件非常适合,因为 express 是从 connect 子类化的(好的 - 原型)
回答by Jared Hanson
If you are looking for an authentication framework for Connect or Express, Passport is worth investigating: https://github.com/jaredhanson/passport
如果您正在寻找 Connect 或 Express 的身份验证框架,Passport 值得研究:https: //github.com/jaredhanson/passport
(Disclosure: I'm the developer of Passport)
(披露:我是 Passport 的开发者)
I developed Passport after investigating both connect-auth and everyauth. While they are both great modules, they didn't suit my needs. I wanted something that was more light-weight and unobtrusive.
在研究了 connect-auth 和 everyauth 之后,我开发了 Passport。虽然它们都是很棒的模块,但它们并不适合我的需求。我想要一些重量更轻、更不引人注目的东西。
Passport is broken down into separate modules, so you can choose to use only what you need (OAuth, only if necessary). Passport also does not mount any routes in your application, giving you the flexibility to decide when and where you want authentication, and hooks to control what happens when authentication succeeds or fails.
Passport 被分解为单独的模块,因此您可以选择仅使用您需要的模块(OAuth,仅在必要时)。Passport 也不会在您的应用程序中安装任何路由,让您可以灵活地决定何时何地进行身份验证,并使用钩子来控制身份验证成功或失败时发生的情况。
For example, here is the two-step process to setup form-based (username and password) authentication:
例如,以下是设置基于表单(用户名和密码)身份验证的两步过程:
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('/');
});
Additional strategies are available for authentication via Facebook, Twitter, etc. Custom strategies can be plugged-in, if necessary.
其他策略可用于通过 Facebook、Twitter 等进行身份验证。如有必要,可以插入自定义策略。
回答by Matthias
Session + If
会话 + 如果
I guess the reason that you haven't found many good libraries is that using a library for authentication is mostly over engineered.
我猜你没有找到很多好的库的原因是使用库进行身份验证大多是过度设计的。
What you are looking for is just a session-binder :) A session with:
您正在寻找的只是一个会话绑定器 :) 一个会话:
if login and user == xxx and pwd == xxx
then store an authenticated=true into the session
if logout destroy session
thats it.
就是这样。
I disagree with your conclusion that the connect-auth plugin is the way to go.
我不同意您的结论,即 connect-auth 插件是可行的方法。
I'm using also connectbut I do not use connect-auth for two reasons:
我也在使用connect但我不使用 connect-auth 有两个原因:
IMHO breaks connect-auth the very powerful and easy to read onion-ring architecture of connect. A no-go - my opinion :). You can find a very good and short article about how connect works and the onion ring idea here.
If you - as written - just want to use a basic or http login with database or file. Connect-auth is way too big. It's more for stuff like OAuth 1.0, OAuth 2.0 & Co
恕我直言,connect-auth 打破了连接的非常强大且易于阅读的洋葱圈架构。禁止 - 我的意见:)。您可以在此处找到一篇关于连接工作原理和洋葱圈创意的非常好的简短文章。
如果您 - 正如所写的那样 - 只想对数据库或文件使用基本或 http 登录。Connect-auth 太大了。更适合像 OAuth 1.0、OAuth 2.0 & Co 这样的东西
A very simple authentication with connect
一个非常简单的连接认证
(It's complete. Just execute it for testing but if you want to use it in production, make sure to use https) (And to be REST-Principle-Compliant you should use a POST-Request instead of a GET-Request b/c you change a state :)
(已完成。只需执行它进行测试,但如果您想在生产中使用它,请确保使用 https)(并且要符合 REST-Principle-Compliant,您应该使用 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
笔记
I wrote this statement over a year ago and have currently no active node projects. So there are may be API-Changes in Express. Please add a comment if I should change anything.
我一年多前写了这个声明,目前没有活跃的节点项目。因此,Express 中可能会有 API 更改。如果我应该更改任何内容,请添加评论。
回答by Tom
I was basically looking for the same thing. Specifically, I wanted the following:
我基本上是在寻找同样的东西。具体来说,我想要以下内容:
- To use express.js, which wraps Connect's middleware capability
- "Form based" authentication
- Granular control over which routes are authenticated
- A database back-end for users/passwords
- Use sessions
- 使用 express.js,它包装了 Connect 的中间件功能
- “基于表单”的身份验证
- 对哪些路由进行身份验证的精细控制
- 用户/密码的数据库后端
- 使用会话
What I ended up doing was creating my own middleware function check_auththat I pass as an argument to each route I want authenticated. check_authmerely checks the session and if the user is not logged in, then redirects them to the login page, like so:
我最终做的是创建我自己的中间件函数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();
}
Then for each route, I ensure this function is passed as middleware. For example:
然后对于每个路由,我确保这个函数作为中间件传递。例如:
app.get('/tasks', check_auth, function(req, res) {
// snip
});
Finally, we need to actually handle the login process. This is straightforward:
最后,我们需要实际处理登录过程。这很简单:
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("/");
}
});
});
At any rate, this approach was mostly designed to be flexible and simple. I'm sure there are numerous ways to improve it. If you have any, I'd very much like your feedback.
无论如何,这种方法主要设计为灵活和简单。我相信有很多方法可以改进它。如果您有任何意见,我非常希望得到您的反馈。
EDIT: This is a simplified example. In a production system, you'd never want to store & compare passwords in plain text. As a commenter points out, there are libs that can help manage password security.
编辑:这是一个简化的例子。在生产系统中,您永远不想以纯文本形式存储和比较密码。正如评论者指出的那样,有一些库可以帮助管理密码安全。
回答by Peter Lyons
回答by b_erb
Here is some code for basic authentication from one of my projects. I use it against CouchDB with and additional auth data cache, but I stripped that code.
这是我的一个项目中的一些基本身份验证代码。我将它与 CouchDB 和额外的身份验证数据缓存一起使用,但我删除了该代码。
Wrap an authentication method around you request handling, and provide a second callback for unsuccessfull authentication. The success callback will get the username as an additional parameter. Don't forget to correctly handle requests with wrong or missing credentials in the failure callback:
围绕您的请求处理包装身份验证方法,并为不成功的身份验证提供第二个回调。成功回调将获取用户名作为附加参数。不要忘记在失败回调中正确处理错误或缺少凭据的请求:
/**
* 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;
}
};
回答by florian
A different take on authentication is Passwordless, a token-based authenticationmodule for express that circumvents the inherent problem of passwords [1]. It's fast to implement, doesn't require too many forms, and offers better security for the average user (full disclosure: I'm the author).
一种不同的身份验证方式是 Passwordless,这是一种基于令牌的身份验证模块,用于绕过密码的固有问题 [1]。它实施起来很快,不需要太多表单,并且为普通用户提供了更好的安全性(完全披露:我是作者)。
[1]:密码已过时
回答by zemirco
A few years have passed and I'd like to introduce my authentication solution for Express. It's called Lockit. You can find the project on GitHuband a short intro at my blog.
几年过去了,我想介绍一下我的 Express 身份验证解决方案。它被称为Lockit。您可以在GitHub 上找到该项目,并在我的博客中找到简短介绍。
So what are the differences to the existing solutions?
那么与现有的解决方案有什么不同呢?
- easy to use: set up your DB, npm install,
require('lockit'),lockit(app), done - routes already built-in (/signup, /login, /forgot-password, etc.)
- views already built-in (based on Bootstrap but you can easily use your own views)
- it supports JSON communication for your AngularJS / Ember.js single page apps
- it does NOT support OAuth and OpenID. Only
usernameandpassword. - it works with several databases (CouchDB, MongoDB, SQL) out of the box
- it has tests (I couldn't find any tests for Drywall)
- it is actively maintained (compared to everyauth)
- email verification and forgot password process (send email with token, not supported by Passport)
- modularity: use only what you need
- flexibility: customize all the things
- 使用方便:设置您的数据库,NPM安装
require('lockit'),lockit(app),做 - 已经内置的路由(/signup、/login、/forgot-password 等)
- 视图已经内置(基于 Bootstrap,但您可以轻松使用自己的视图)
- 它支持 AngularJS / Ember.js 单页应用程序的 JSON 通信
- 它不支持 OAuth 和 OpenID。只有
username和password。 - 它开箱即用,适用于多个数据库(CouchDB、MongoDB、SQL)
- 它有测试(我找不到干墙的任何测试)
- 它被积极维护(与everyauth相比)
- 邮件验证和忘记密码流程(使用令牌发送邮件,Passport 不支持)
- 模块化:只使用你需要的
- 灵活性:定制所有的东西
Take a look at the examples.
查看示例。
回答by lk145
There is a project called Drywallthat implements a user login system with Passportand also has a user management admin panel. If you're looking for a fully-featured user authentication and management system similar to something like what Django has but for Node.js, this is it. I found it to be a really good starting point for building a node app that required a user authentication and management system. See Jared Hanson's answerfor information on how Passport works.
有一个名为Drywall的项目,它使用Passport实现了一个用户登录系统,并且还有一个用户管理管理面板。如果您正在寻找功能齐全的用户身份验证和管理系统,类似于 Django 所拥有的但适用于 Node.js 的系统,就是这样。我发现它是构建需要用户身份验证和管理系统的节点应用程序的一个非常好的起点。有关Passport 工作原理的信息,请参阅Jared Hanson 的回答。
回答by Soman Dubey
Here are two popular Github libraries for node js authentication:
下面是两个流行的用于节点 js 身份验证的 Github 库:
https://github.com/jaredhanson/passport( suggestible )
https://github.com/jaredhanson/passport(建议)

