ajax实例里面的函数BearerToken的相关定义与使用方法
来龙去脉
诸如Ember,Angular,Backbone之类的前端框架类库正随着更加精细的Web应用而日益壮大。正因如此,服务器端的组建也正在从传统的任务中解脱,转而变的更像API。API使得传统的前端和后端的概念解耦。开发者可以脱离前端,独立的开发后端,在测试上获得更大的便利。这种途径也使得一个移动应用和网页应用可以使用相同的后端。
当使用一个API时,其中一个挑战就是认证(authentication)。在传统的web应用中,服务端成功的返回一个响应(response)依赖于两件事。
一是,他通过一种存储机制保存了会话信息(Session)。每一个会话都有它独特的信息(id),常常是一个长的,随机化的字符串,它被用来让未来的请求(Request)检索信息。
其次,包含在响应头(Header)里面的信息使客户端保存了一个Cookie。服务器自动的在每个子请求里面加上了会话ID,这使得服务器可以通过检索Session中的信息来辨别用户。这就是传统的web应用逃避HTTP面向无连接的方法(This is how traditional web applications get a
round the fact that HTTP is stateless)。
API应该被设计成无状态的(Stateless)。这意味着没有登陆,注销的方法,也没有sessions,API的设计者同样也不能依赖Cookie,因为不能保证这些request是由浏览器所发出的。自然,我们需要一个新的机制。这篇文章关注于JSON Web Tokens,简写为JWTs,一个可能的解决这个问题的机制。
这篇文章利用Node的Express框架作为后端,以及Backbone作为前端。
常用方法
第一个是使用在HTTP规范中所制定的Basic Auth, 它需要在响应中设定一个验证身份的Header。客户端必须在每个子响应是附加它们的凭证(credenbtial),包括它的密码。如果这些凭证通过了,那么用户的信息就会被传递到服务端应用。
第二个方面有点类似,但是使用应用自己的验证机制。通常包括将发送的凭证与存储的凭证进行检查。和Basic Auth相比,这种需要在每次请求(call)中发送凭证。
第三种是OAuth(或者OAuth2)。为第三方的认证所设计,但是更难配置。至少在服务器端更难。
在使用中,并不会每次都让用户提交用户名和密码,通常的情况是客户端通过一些可靠信息和服务器交换取token,这个token作为客服端再次请求的权限钥匙。Token通常比密码更加长而且复杂。比如说,JWTs通常会长达150个字符。一旦获得了token,在每次调用API的时候都要附加上它。然后,这仍然比直接发送账户和密码更加安全,哪怕是HTTPS。
把token想象成一个安全的护照。你在一个安全的前台验证你的身份(通过你的用户名和密码),如果你成功验证了自己,你就可以取得这个。当你走进大楼的时候(试图从调用API获取资源),你会被要求验证你的护照,而不是在前台重新验证。
JWT(JSON Web Token)
JWTs是一份草案,尽管在本质上它是一个老生常谈的一种更加具体的认证授权的机制。一个JWT被周期(period)分成了三个部分。JWT是URL-safe的,意味着可以用来查询字符参数。(译者注:也就是可以脱离URL,不用考虑URL的信息)。
JWT的第一部分是对一个简单js对象的编码后的字符串,这个js对象是用来描述这个token类型以及使用的hash算法。下面的例子展示的是一个使用了HMAC SHA-256算法的JWT token。
{
"typ" : "JWT",
"alg" : "HS256"
}
在加密之后,这个对象变成了一个字符串:
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
JWT的第二部分是token的核心,这部分同样是对一个js对象的编码,包含了一些摘要信息。有一些是必须的,有一些是选择性的。实例如下:
{
"iss": "joe",
"exp": 1300819380,
"": true
}
这个结构被称为JWT Claims Set。这个iss是issuer的简写,表明请求的实体,可以是发出请求的用户的信息。exp是expires的简写,是用来指定token的生命周期。(相关参数参看:the document)加密编码之后如下:
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
JWT的第三个部分,是JWT根据第一部分和第二部分的签名(Signature)。像这个样子:
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
最后将上面的合并起来,JWT token如下:
Jpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
处理Tokens
我们将用JWT simple模块去处理token,它将使我们从钻研如何加密解密中解脱出来。如果你有兴趣,可以阅读这篇说明,或者读这个仓库的源码。
首先我们将使用下面的命令安装这个库。记住你可以在命令中加入–save,让其自动的让其加入到你的package.json文件里面。
npm install jwt-simple
在你应用的初始环节,加入以下代码。这个代码引入了Express和JWT simple,而且创建了一个新的Express应用。最后一行设定了app的一个名为jwtTokenSecret的变量,其值为'YOUR_SECRET_STRING’(记得把它换成别的)。
var express = require('express');
var jwt = require('jwt-simple');
var app = express();
app.set('jwtTokenSecret', 'YOUR_SECRET_STRING');
获取token
我们需要做的第一件事就是让客户端通过他们的账号密码交换token。这里有2种可能的方法在RESTful API里面。
第一种是使用POST请求来通过验证,使服务端发送带有token的响应。
此外,可以使用GET请求,这需要他们使用参数提供凭证(指URL),或者更好的使用请求头。
这篇文章的目的是为了解释token验证的方法而不是基本的用户名/密码验证机制。所以我们假设我们已经通过请求得到了用户名和密码:
User.findOne({ username: username }, function(err, user) {
if (err) {
// user not found
return res.send(401);
}
if (!user) {
// incorrect username
return res.send(401);
}
if (!user.validPassword(password)) {
// incorrect password
return res.send(401);
}
// User has authenticated OK
res.send(200);
});
如果用户成功验证账号和密码,然后我们生成一个token,返回给用户。
var expires = moment().add('days', 7).valueOf();
var token = de({
iss: user.id,
exp: expires
}, ('jwtTokenSecret'));
res.json({
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论