细谈Node.js项目实战

     使用node.js开发的token用户验证的网站不少,典型的网站,如猪八戒威客网站,使用了node.js技术。 node

在网站应用中,会为不一样的用户赋予不一样的权限(好比为管理员帐户赋予较高的权限),因此咱们须要在auto()函数中添加用户认证的流程。 算法

通常来说,最多见的方案是基于cookie 或session 受权管理,但某些场景下这种方案并不适用,好比对要求使用REST 架构的应用,或客户端对cookie\session 支持不佳(如移动端)等。更有效的方案是在每次请求中都携带token(比较常见的OAuth2.0 协议3),并在服务端经过token 进行独立的认证。这里既能够把token 字段加载到请求参数中,也能够添加到HTTP 请求头中。固然这里也能够是其余认证信息,好比E-mail 和密码、API 密钥、API 密码等。 数据库

在咱们的示例中,每一个请求都会提交token 字段,并在接收时把token(经过req.query.token 获取)和应用中储存的token(一般使用数据库储存,或如本例中简单地保存在SECRET_TOKEN 常量中)进行比对。若是比对经过则调用next()方法继续后续处理,若是不经过则调用next(error)触发Express.js 的错误响应:
  express

 
  1. var auth = function(req, res, next) {  
  2. if (req.query.token && token === SECRET_TOKEN) {  
  3. // 校验经过,进行下一阶段处理  
  4. return next();  
  5. } else {  
  6. return next(new Error('Not authorized'));  
  7. // 也能够 res.send(401);  
  8. }  
  9. }; 

在实践中,通常使用API 的key 和secret 生成HMAC-SHA1(一种基于散列的信息加密算法)字符串,并把它和接收到的token(req.query.token)进行比对。 后端

注意 在调用next()方法时传入一个error 对象做为参数,表示放弃请求处理,这时会触发Express.js 的错误模式,并进入错误处理流程。 api

咱们刚才介绍了REST API 中经常使用的基于token 的认证模式。另一种常见模式是使用cookie 进行用户认证,这种模式在含有用户界面的应用中常用。咱们使用cookie 储存session ID,并在请求时自动提交。从某种意义上讲,cookie 有些相似于token,可是cookie使用较为方便,并不须要开发者作太多的工做。基于session 的认证就是使用这种模式。基于session 的认证在Web 应用中十分常见,也更受推崇,由于浏览器能够自动处理带有session 的请求头,并且大多数的后端平台或框架也能原生支持session。接下来,就让咱们一块儿进入在Node.js 中实现基于session 的用户认证这一小节吧。 浏览器

   

基于session 的用户认证 安全

基于session 的用户认证借助于请求体对象req 中的session 对象完成。简单地说,session 能够鉴别客户端,并对应地储存信息,供同一客户端全部的后续请求读取。 服务器

在Express.js 4.x 版(4.1.2 版以及写本书时使用的4.2.0 版)中,咱们须要手动引入(require())操做session 所依赖的模块,由于Express.js 4.x 把它们从核心包中剔除了。例如,引入并使用cookie-parser 和express-session 模块:
  cookie

 
  1. var session = require('express-session');  
  2. ...  
  3. app.use(cookieParser());  
  4. app.use(session()); 

固然,在进行这些操做以前,cookie-parser 模块和express-session 模块须要经过NPM 安装到项目的node_modules 文件夹中。

若是是在经典的Express.js 3.x 版本中,则须要在配置文件中加入下面两个中间件。

1. express.cookieParser():解析发送的和接收的cookie。

2. express.session():在每一个请求体中暴露res.session 对象,而且在内存或持久化存储中(如MongoDB、Redis 等)储存session 数据。

在后文的例子中,若是没有特别说起Express.js 的版本,就表示代码能兼容3.x 和4.x
版本。

啰唆一句,咱们能够在req.session 中储存任何数据,它们会自动出如今来自同一个客户端的全部后续请求中(在客户端支持cookie 的前提下)。在这个例子中,认证信息用session 储存的一个标记(布尔值),咱们在受权函数中去检查这个标记,为真放行,为假则退出。像这样敲击代码:

 
  1. app.post('/login', function(req, res, next) {  
  2. // 检查凭证  
  3. // 在请求的有效负载中进行传递  
  4. if (checkForCredentials(req)) {  
  5. req.session.auth = true;  
  6. res.redirect('/dashboard'); // 非公开内容  
  7. } else {  
  8. res.send(401); // 认证不经过  
  9. }  
  10. }); 

警告 避免在cookie 中储存任何敏感信息。由于cookie 十分不安全,并且储存长度存在限制(不一样的浏览器限制不一样,IE 最小)。因此推荐的方法是:不去手动操做cookie,cookie 中只保留session ID 字段,这个字段由Express.js 中间件自动控制。

Express.js 默认使用内存来储存session 数据,这就表示每次应用崩溃或手动重启时session 数据都会丢失。咱们可使用Redis 或者MongoDB 储存session 数据,这样既能够保证session 数据可以持久化存储也能够实现session 数据可跨服务器读取

为你的博客增长邮箱和密码登陆功能

你的博客中实现基于session 的用户认证,咱们须要完成如下步骤:

1. 在app.js 的配置部分中增长引入和使用session 中间件的代码。

2. 实现一个基于session 的用户认证中间件,以便咱们在多个路由规则之间复用这些代码。

3. 在app.js 文件中添加上一步骤中的中间件,以控制非公开页面的访问。像这样:

app.get('/api/', authorize, api.index)

4. 在user.js 中实现包含认证过程的登陆路由POST /login 和登出路由GET/logout。  

相关文章
相关标签/搜索