最新消息:

选择合适的 Node.js 认证策略(Choosing Your Node.js Authentication Strategy )

服务器 William 708浏览

Node is blowing up!  I’ve been working and playing with Node since 2010 and in that time I’ve seen it go from a tiny community of people hacking side projects to a full-fledged and legit movement of modern developers building very real, very important, and very large applications.  A whole ecosystem of solutions has sprung up to help Node developers, and that ecosystem is rapidly evolving.  But it’s increasingly hard to figure out what solutions are best for you because of all the noise in a Google search or in npm.

Authentication and user management in particular is a difficult and shifting landscape.  And yet, when building a real application in Node, it is one of the first components you need to figure out.  This guide aims to give you a complete lay of the land for user management and authentication in node.

Node正在兴起!我从2010年就开始玩并使用Node工作,那个时侯我看着它从一个小的个人hack项目成长为一个能够供开发者使用来构建真实、重要及大型应用的全面型构建工具。生态系统型解决方案如雨后春笋般涌现,在助力开发者的同时使生态系统也迅速发展着。但随着它的快速增长也越来越难找到最适合你的解决方案,因为来自谷歌搜索或npm的干扰。

认证和用户管理绝对是块困难且变化多端的战场。然而,当创建一个实际的Node应用时,这却是第一位需要确认的组件。本指南的目的是给你展现Node中用户管理和认证的全面。

What is available in Node?

Node today has several different paths to build user management. In no particular order there are:

  • Passport.js / Everyauth

  • Your Own Database and a Hashing Algorithm

  • User Management as a Service

Passport.js / Everyauth

PassportJS and Everyauth are authentication middleware for node that leverage the Connect middleware conventions.  That means if you are using a framework like Express, Restify, or Sails you can easily plug one of their authentication schemes (or strategies) directly into your application.  Everyauth comes with their strategies embedded, where as with Passport you can pick and choose which strategies to use. Some of the common strategies that developers use with Passport are Facebook and Google, but it also include everything from a local username/password authentication, to a slew of OpenID and OAuth providers, and even a Stormpath strategy for Passport.

Node中有哪些可用选择?

目前Node中有几个不同的路径来构建用户管理。它们的无序排列如下:

  • Passport.js / Everyauth

  • 自己的数据库及哈希算法

  • 用户管理即服务

Passport.js / Everyauth

PassportJSEveryauth是一个Node处理连接中间件协议的认证中间件。这意味着如果你使用ExpressRestifySails等框架,你就可以很容易地将其中一个认证方案(或策略)直接插入你的应用中。Everyauth配合其嵌入策略,就像通行证时可以选择使用的策略一样。一些开发者的经常配合通行证使用的策略是FacebookGoogle的,但这也包括诸如本地用户名/密码认证到一系列的OpenID、OAuth提供器等的一切,甚至是一个Stormpath通行策略。

Even though Everyauth and Passport are built on top of the same middleware framework, they have their own sets of pros and cons. Passport is more flexible and modular, but Everyauth provides additional functionality that helps with routes and login/registration views.  For a lot of Node developers Passport is also preferred because it does not use promises.

Since Passport and Everyauth are built on Connect, both will help you with session management, including:

  • Serialization of the authenticated user

  • Managing the session

  • Logging the user out

Additionally, they are designed for simple, easy authentication, but fall short (by design) of broader user management needs.  You are still left to design, implement, and maintain all your other user infrastructure.

尽管 Everyauth 和 Passport 都建立在同一个中间件框架之上,他们有自己的一套利弊。Passport 更加灵活和模块化的,但 Everyauth 提供了对路由和登录/注册有所帮助的额外的功能。对于很多 Node 开发员,Passport 也是首选的,因为它不使用承诺。 

由于 Passport 和 Everyauth 都是建立在 Connect 上的,他们都将帮助你实现会话管理,其中包括: 

  • 序列化经过身份验证的用户

  • 会话管理

  • 注销用户 

此外,它们非常适用于简单和容易的用户验证,但由于设计上的局限,并不适用于属于更广泛的用户管理需求。你还是需要设计,实施和维护其他用户验证需要的基础设施。

For example, if you are using passport-local (the strategy to authenticate username / password against your own database), Passport does not handle user signup and account verification.  You will need to work with database modules to authenticate to a database, create the account, track verification status, create a verification token, send an email, and verify the account.  This means a developer will need to worry about URL safety, removing expired tokens, and other security constraints (like hashing the password correctly in a database).

Your Own Database and a Hashing Algorithm

The do-it-yourself approach doesn’t rely on any middleware.  You choose your own stack, a database to store users (likely PostgresSQL and MongoDB) and a hashing algorithm to generate password hashes (likely bcrypt and scrypt). Searching for bcrypt or scrypt in npm will result in quite a few modules of varying degrees of quality, each with their own sets of dependencies. Be particularly careful if you are a Windows developer – we recommend the native JS implementation of bcrypt.

例如,如果你使用的是本地通行证(针对自己数据库的用户名密码验证策略),Passport 没有处理用户的注册及账户的验证。你需要使用数据库模块来进行身份鉴定,创建账户,追踪验证状态,创建验证令牌,发送邮件,以及验证账户。这意味着开发者会需要担心 URL 的安全性,移除过期的令牌,以及其它的安全约束(如数据库中密码的正确散列)。

自己的数据库及哈希算法

DIY 的方法不依赖于任何中间件。选择自己的栈,存储用户所用的数据库(可能是 PostgresSQL 或 MongoDB),以及一个用来生成密码散列的哈希算法(可能是 bcrypt 或 scrypt)。在 npm 中搜索 bcrypt 或 scrypt 会导致不少模块在质量上的变化,每个模块都有自己的依赖集合。如果你是 Windows 开发者,请特别注意 – 我们推荐 Javascript 原生实现的 bcrypt 。

After deciding on a stack, you will need to build out user management and authentication.  Historically this approach has been extremely common, but is tedious, prone to error, and requires more maintenance than other approaches.

You will need to build/figure out:

  • Account Creation

    • Create a user schema to hold user data

    • Create accounts and store salt + hashed passwords using bcrypt / scrypt

    • Sending an email with token for account verification

  • Account Authentication

    • Authenticate the user (comparing hashes)

  • Account Management

    • Generating / invalidating tokens

    • Password reset work flow

    • Role-based access / permissions

  • Integrations with ID and Social Providers

  • Secure the system

    • Secure the Database from unauthorized access

    • Secure the OS from unauthorized access

  • Backups for data

选定栈后,你需要增加用户管理和身份验证。从历史上看,这种方式极其常见,但是与其它方式相比,它冗长乏味、易于出错、需要更多的维护。

你需要增加/解决:

  • 账户创建

    • 创建用户模式来保持用户数据

    • 创建账户及存储那些使用 bcrypt / scrypt 盐化(增加随机字串)、散列过的密码

    • 发送带有账户验证令牌的邮件

  • 账户身份验证

    • 验证用户身份(比较散列值)

  • 账户管理

    • 生成 / 失效令牌

    • 密码复位的工作流

    • 基于角色的访问/许可

  • ID 与 社会服务提供商的集成

  • 系统安全

    • 保护数据库以免于未授权访问

    • 保护操作系统以免于未授权访问

  • 数据备份

One of the biggest challenges with rolling your own auth and user management, is the maintenance.  Take password hashing as an example.   Done right, you select a cost factor that makes your hashing algorithm purposely slow (roughly 300-700ms) to prevent brute force attacks.   However, Moore’s Law is a bitch— compute price/performance doubles every year.  So the right cost factor today, may be considered insecure tomorrow.  If you’re building applications that will go into production, its your responsibility to update your hashing strategy at least once a year.

Despite the Node community’s aversion to “rolling your own” middleware, there are a few benefits to this approach.  You get complete control of your infrastructure.  If the tools available to you are not “good enough” for what you need to deliver to your customer, then you have the ability to invest engineering effort and time to innovate around user authentication and user management.  Luckily, very few applications and developers have those kind of requirements, so the open source tools and API services available today help them move faster and deliver more.

玩转自己的身份验证和用户管理的最大的挑战是,维护。以密码散列为例。方式正确的话,你选择了一个成本因素,为了防止暴力攻击特意使得你的散列算法缓慢(大约 300-700 毫秒)。不管怎样,摩尔定理是个婊子 — 计算的性价比每年折半。所以今天正确的成本因素,在明天就可能被认作是不可靠的。如果你正在创建可能会交付成产品的应用程序,至少每年更新一次散列策略是你的责任。

尽管 Node 社区很反感“玩转你自己的”中间件,这种方式也有一些好处。你可以完全控制自己的基础设施。如果对你可用的工具还没有“好到”可以发布给你的客户,那么你就有能力围绕身份验证和用户管理投入时间和精力去创新。幸运的是,应用程序和开发者很少有这种需求,所以开源工具以及现在可用的 API 服务,帮助他们推进更快、发布更多。

User Management as a Service

Over time, software has moved from on premise, to the cloud, to distributed API services. At the same time, development teams have come to rely on open source software and API services as much as their own code.  It is now possible to offload user management to a system that exposes user management functionality via REST APIs and open-source SDKs for application development. Stormpath falls into this category along with some user API startups.  The Node community, in particular, has adopted this service oriented paradigm more than any other community to date.

Typically, API-driven services allow for more common functionality around user management, going beyond just authentication. The additional functionality varies by provider, but usually includes:

  • Account email verification

  • Password reset work flows

  • Role based access / permissions

  • Schema-less User Profiles

  • Two-factor authentication

  • Single sign on between applications

  • Social login integration (Facebook, Google, etc)

  • Integration to Node auth middleware like Passport

用户管理即作为一个服务

随着时间的推移,软件已经从本地软件,到云端发布,到分布式的API服务。与此同时,开发团队已经开始依赖于开源软件和API的服务, 甚至超过自己的代码。现在可以将用户管理卸载给新的系统, 这个新的系统通过REST API和开源的SDK来管理应用程序的开发。 Stormpath 以及一些开发用户API的初创公司就属于这一类,。特别是Node社区,已经远超其他任何社区采用了这种面向服务的模式。

通常情况下, API 驱动的服务在用户的管理上允许更加常见的功能,远远不止限于验证。这些附加功能根据提供商而不同,但通常包括:

  • 帐户电子邮件验证

  • 密码重置工作流程

  • 基于角色的访问/权限

  • 无模式的用户配置文件

  • 双重因素身份验证

  • 在应用程序之间的单点登录

  • 社交登录的集成( Facebook,谷歌等)

  • 集成到Node验证的中间件例如 Passport 

In addition to pure features, they also off-load much of the security and operations.  They host all the infrastructure for you, scale to absorb your peak traffic, and handle on-going security of your user data.

Offloading to an API service generally delivers convenience and improved security, while reducing development and maintenance costs.   Developers now get to focus on building unique parts of their application.

However, there are trade-offs with using API services.  You are introducing a 3rd party dependency to your application.  It needs to be highly available,  fast, portable, provide security during transport, and be flexible enough to meet your user data model.

Availability and performance are extremely important because a critical system like user authentication and management can not be offline or slow.  Caching in their SDKS and being based on modern cloud infrastructures is a good start, but it is important that the service is prepared for the worst case scenarios – like whole data centers going down.  And if you build on top of a service for user management, make sure you can subscribe to notifications of any outages.

除了这些纯粹的功能,它也提供相当可靠的安全性和操作性。为用户提供所有基础设施,延伸到吸收用户的流量高峰以及处理用户数据的安全问题。

卸载一个API服务通常可以提供更多的便利性和更高的安全性,同时也降低开发和维护的成本。开发人员可以集中更多的注意力打造属于自己的应用程序的独特部分。

不过有时用户也需要权衡的使用API服务。当你引用一个第三方的依赖性服务到你的应用中。它需要具有高可用,快速,便携,传输过程中提供可靠的安全性,并具有足够的灵活性,以满足用户的数据模型需要。

可用性和性能是至关重要的,因为对于一个特定的系统,如用户认证和管理不可能是离线状态或者时间很短。缓存到他们的SDK和基于现代云计算基础架构是不错的开始,但重要的是,该服务即将面临到最糟糕的情况 - 例如整个数据中心正在走下坡。因此你想要确保您可以收到任何的通知,则需要建立在用户管理服务的顶部。

Data portability is also critical – can you move user data in and out in safe (and easy) ways. While its easy to write a script to port unencrypted data over JSON, the ease of porting passwords will heavily depend on how you have stored any pre-existing data.  For example, bcrypt is very portable by design, as it follows Modular Crypt Format (MCF). It is possible for multiple systems and languages to understand how to construct the hash by looking at the hash value itself. If you’re building a prototype and don’t use a service like Stormpath, we recommend starting with an MCF hash like bcrypt – it will be much easier to upgrade in the future.

Transport security between your application and the API Service is important in this approach compared to the approaches above.  The additional network communication needs to be secured.  For example, Stormpath supports only HTTPS and uses a custom digest auth algorithm to guard against replay and man in the middle attacks. You can read more about our security here.

数据移植也很关键 – 你能够安全的(并且容易的)来回移动数据。与轻松写出在 JSON 上移植未加密数据的脚本不同,移植密码的难易程度严重依赖于任何已存在的数据的存储方式。例如,bcrypt 设计的就很容易移植,因为它遵循模数加密格式(MCF)。对许多系统和语言而言, 通过查看散列值本身来理解怎样构造散列是可能的。如果你在建立一个原型,没有使用 Stormpath 之类的服务,我们推荐以类似 bcrypt 之类的 MCF 散列开始 – 在将来升级时会更容易。

与之前的实现方式相比,这种实现方式中,在你的应用程序和 API 服务之间的传输安全更加重要。额外的网络通讯需要安全化。例如,Stormpath 仅仅支持 HTTPS,使用一个特定摘要验证算法来确保,不会被回放和中间人攻击。关于安全性你可以在这里了解更多。

The data model used by authentication services can vary widely – Salesforce, for instance, looks very different from the Stormpath data model, which is based on directories and therefore generic and flexibly. It’s worth digging in to make sure that the data model you have planned for your application, is supported by the service. This is particularly true for mulit-tenant applications or SaaS.

Additionally, documentation of APIs varies widely – you should make sure your solution outlines what you need before you dive in.

Building User Management…

…is hard. Inside node there are different solutions, each with a set of pros and cons.  I hope this post helps you get the lay of the land.   If you have any questions, suggestions or experiences that you want to share, feel free to leave a comment or reach out to me on twitter @omgitstom.  And if you’re interested in a User Management API service, check out Stormpath and our Official Node SDK.

数据模型所使用的授权服务很广泛。以Salesforce为例,看起来非常不同于Stormpath数据模型,正是基于目录,因此,它是通用和灵活的。它值得你为你的应用支持这个数据模型服务。这对于多承租人应用或者SaaS尤其有效。此外,API文档变化很大——你应该确保你在努力开始做事之前细致地了解大纲。

建立用户管理

这是很困难的。内部节点有不同的解决方案,每一组都有优点和缺点。我希望这篇文章帮助你看到这些情况。如果你有任何问题,建议或者体验想要分享,留下你的评论或者在twitter上联系我@omgitstom。如果你对用户管理API服务(User Management API service)感兴趣,请查看Stormpath和我们的Official Node SDK


via:oschina

转载请注明:AspxHtml学习分享网 » 选择合适的 Node.js 认证策略(Choosing Your Node.js Authentication Strategy )