文档章节

AngularJS+Satellizer+Node.js+MongoDB->Instagram-12

开源中国匿名会员
 开源中国匿名会员
发布于 2015/02/02 07:50
字数 1049
阅读 140
收藏 1

Build an Instagram clone with AngularJS, Satellizer, Node.js and MongoDB

#12.授权中间件和 JWT

把下面的方法加到 app.use() 中间件后面去。其实这个方法放在 server.js 哪里都无所谓,知识我们要确保我们在这篇教程里面能比较容易找到。这是一个单纯的 JavaScript 方法,把用户对象当成参数,然后返回一个 token 字符串。

<!-- lang: js -->
function createToken(user) {
  var payload = {
    exp: moment().add(14, 'days').unix(),
    iat: moment().unix(),
    sub: user._id
  };
 
  return jwt.encode(payload, config.tokenSecret);
}

我用 Moment.js 来生成当前时间和两周之后的日期。你可以用 JavaScript 的内置 Date 对象,但是肯定没有我上面的简洁漂亮。

我们用的 JWT 库(jwt-simple) 中要用到的是这两个方法: encode()decode()。用于 encoded 和 decoded 的对象称之为 JWT Claims,很多地方也把它叫做 payload。你可以在这里查阅到完整的 JSON Web Token 规范草案。上面的这些 claims 都不是必须的 – exp (过期时间), iat (发行日), sub (摘要) 。作为开发者,这都由你控制,根据你的用例来决定 JWT claims 应该包含什么内容。就像我之前提到过的,你甚至可以包含整个用户对象作为 JWT Claims 的一部分,不过通常都是 email 或者 user_id 。

最后 第 5 行sub claim 被用来保存用户的唯一标识符 (MongoDB ObjectId),用于标识特定用户。你要问为什么我会用 sub 来代替 id 或者 user_id?我乐意啊,不过也是因为看到 Google 在 OAuth 2.0 OpenID Connect 中也跟我一样用它来作为用户唯一标识符:

https://hackhands.com/wp-content/uploads/2014/10/Screenshot-2014-10-31-22.11.02.png

接下来的功能是负责阻止未经授权的用户访问受限的路由.举例来说,除非用户得到授权,否则我们是不会希望他们访问 /api/feed 路由(Instagram feed)的。

<!-- lang: js -->
function isAuthenticated(req, res, next) {
  if (!(req.headers &amp;amp;amp;&amp;amp;amp; req.headers.authorization)) {
    return res.status(400).send({ message: 'You did not provide a JSON Web Token in the Authorization header.' });
  }
 
  var header = req.headers.authorization.split(' ');
  var token = header[1];
  var payload = jwt.decode(token, config.tokenSecret);
  var now = moment().unix();
 
  if (now &amp;amp;gt; payload.exp) {
    return res.status(401).send({ message: 'Token has expired.' });
  }
 
  User.findById(payload.sub, function(err, user) {
    if (!user) {
      return res.status(400).send({ message: 'User no longer exists.' });
    }
 
    req.user = user;
    next();
  })
}

2-4 行 我们首先检查了 HTTP 请求是否有 Authorization 头。为啥?因为 Satellizer 会拦截所有发出的请求,自动的把 JSON Web Token 加到请求头中。如果你想看看 Satellizer 源码的话,下面是负责这部分内容的代码:

<!-- lang: js -->
$httpProvider.interceptors.push(['$q', function($q) {
  var tokenName = config.tokenPrefix ? config.tokenPrefix + '_' + config.tokenName : config.tokenName;
  return {
    request: function(httpConfig) {
      var token = localStorage.getItem(tokenName);
      if (token) {
        token = config.authHeader === 'Authorization' ? 'Bearer ' + token : token;
        httpConfig.headers[config.authHeader] = token;
      }
      return httpConfig;
    },
    responseError: function(response) {
      return $q.reject(response);
    }
  };
}]);

当然给你看你也不一定能看懂,我只是想说,为什么我们要在 Express 中检查在请求头里面是否有授权内容。提一句,你可以用 Google Chrome 的开发者工具下面的 Network 来查看:

https://hackhands.com/wp-content/uploads/2014/11/Screenshot-2014-11-09-18.08.27.png

好了,回到 isAuthenticated() 中间件方法。检查完 Authorization 头是否存在之后,我们需要用生成令牌时候的加密字符串来解码令牌。解码之后令牌会变回原来的 claims 对象,比如:

<!-- lang: js -->
{ exp: 1416796466,
  iat: 1415586866,
  sub: '546024329ac4d00000db0e09' }

注意: 在做所有的的操作之前都检查 JSON Web Token 的确是个好主意。这个中间件假定我们会得到以下格式的令牌: Authorization: Bearer [token]。查看auth0/node-jsonwebtoken source code (从 34 到 84 行)获取更多信息。

首先,检查有效期。我有设置 14 天的令牌有效期,不过,大家的用例都不一样。如果你要做一个设计大量敏感信息的应用,你可以设置过期时间为 1 小时或者更少。

如果令牌没有过期,我们就可以继续检索数据库的文档。在 第 20 行,我们临时 “保存” 用户对象到请求对象中。这样我们可以在 protected 路由里面,通过调用 req.user 来获取用户的信息。比如说:

<!-- lang: js -->
app.get('/protected', isAuthenticated, function(req, res) {
  // Prints currently signed-in user object
  console.log(req.user);
});

最后我们通过执行 next() 来结束中间件,这个标签告诉 Express 继续执行路由处理。

© 著作权归作者所有

开源中国匿名会员
粉丝 78
博文 104
码字总数 113453
作品 2
徐汇
技术主管
私信 提问
AngularJS+Satellizer+Node.js+MongoDB->Instagram-20

[Build an Instagram clone with AngularJS, Satellizer, Node.js and MongoDB][1] 20.部署 在 instagrame 目录下创建一个新的文件 .gitignore,把 node_modules 加到它里面。你可以直接用命......

开源中国匿名会员
2015/02/02
0
0
AngularJS+Satellizer+Node.js+MongoDB->Instagram-21

[Build an Instagram clone with AngularJS, Satellizer, Node.js and MongoDB][1] 21.总结 完结撒花!这是我那些年写过的最长的贴了。搞笑的是,我在 [TV Show Tracker blog post][2] 里面也...

开源中国匿名会员
2015/02/02
0
0
一个下载 Instagram图片的App:InsViewer

一个下载 Instagram图片的App:InsViewer 编辑于 18:18 文章被以下专栏收录

背着灯笼
2018/08/26
0
0
Instagram 在 PyCon 2017 的演讲摘要

作者:@朱雷 原文链接:Instagram 在 PyCon 2017 的演讲摘要 PyCon 简介 PyCon 是全世界最大的以 Python 编程语言 为主题的技术大会。大会由 Python 社区组织,每年举办一次。在大会上,来自...

董伟明
2017/05/31
0
0
day59-20180817-流利阅读笔记

假·照骗,真·社交焦虑 雪梨 2018-08-17 1.今日导读 发朋友圈之前,不少人为了展现更美好的生活状态会对照片加以“微调”,或是加个滤镜显得逼格更高,或是磨个皮瘦个脸拉个大长腿。现在,国...

飞鱼说编程
2018/08/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

偶遇 JDK 1.8 还未修复的 SecureRandom.getInstance("SHA1PRNG") 之 bug

楼主今天兴高采烈的在部署环境,下载 JDK,打包项目,上传至服务器。 配置 JDK ,打包上传项目楼主就不在这里重复了,读者自行解决哈! 1. 启动项目 java -jar xxxx.jar 令楼主没有想到的是:...

Ryan-瑞恩
15分钟前
7
0
【更新】Stimulsoft Reports v2019.3.1发布,新增对OData v4的支持功能

下载Stimulsoft Report.Ultimate v2019.3.1试用版 集所有报表解决方案于一体的综合性平台 Stimulsoft Reports.Ultimate是集所有报表解决方案于一体的综合性平台,拥有在JavaScript、ASP.NET...

xiaochuachua
15分钟前
1
0
JVM源码分析之javaagent原理完全解读

JVM源码分析之javaagent原理完全解读 概述 本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员,而且agent都是用Java编写的,不需要太多的C/C++编程基础,不过这篇文章里也会讲...

BryceLoski
21分钟前
1
0
git记住密码

git取消记住密码 git config --system --unset credential.helper git记住密码 git config --global credential.helper store...

大灰狼wow
22分钟前
2
0
java 面试知识点笔记(十四)异常体系

问:Error和Exception的区别? ps:Throwable上层是Object Error:程序无法处理的系统错误,编译器不做检查 Exception:程序可以处理的异常,捕获后可能恢复 RuntimeException:不可预知的,...

断风格男丶
25分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部