简介
JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息。此信息可以通过数字签名进行验证和信任。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。
使用场景
授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,允许用户访问该令牌允许的路由,服务和资源。Single Sign On是一种现在广泛使用JWT的功能,因为它的开销很小,并且能够在不同的域中轻松使用。
信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为JWT可以签名 - 例如,使用公钥/私钥对 - 您可以确定发件人是他们所说的人。此外,由于使用标头和有效负载计算签名,您还可以验证内容是否未被篡改。
组成结构
JSON Web令牌由三个部分组成(由点(.)分隔,它们是:
- 头
- 有效载荷
- 签名
因此,JWT通常如下所示。
xxxxx.yyyyy.zzzzz
头
标头通常由两部分组成:令牌的类型,即JWT,以及正在使用的散列算法,例如HMAC SHA256或RSA。
{
"alg": "HS256",
"typ": "JWT"
}
然后,这个JSON被编码为Base64Url,形成JWT的第一部分。
有效载荷
{
"name": "大明",
"_id": "123",
"iat": 1534774285, //JWT生成时间
"exp": 1534777885 //过期时间
}
然后,有效负载经过Base64Url编码,形成JSON Web令牌的第二部分。
签名
要创建签名部分,您必须采用编码标头,编码的有效负载,秘密,标头中指定的算法,并对其进行签名。
例如,如果要使用HMAC SHA256算法,将按以下方式创建签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
在koa中使用JWT
npm install jsonwebtoken --save-dev //生成JWT
npm install koa-jwt --save-dev //验证JWT
在controller中
//userController.js
const jwt = require("jsonwebtoken");
const cert = require("../../config/config").cert; //秘钥
exports.login = async (ctx, next) => {
return (ctx.body = {
token: jwt.sign(
{
name: "大明",
_id: "123"
},//这里的数据可以是我们登录成功返回的一些用户数据
cert,
{ expiresIn: 60 * 60 } //时间间隔
)
});
};
这样用户通过登录就可以接收到服务器返回的token
客户端请求受保护的服务器资源时需要携带token否则不允许访问。
//app.js
const koajwt = require("koa-jwt");
// 错误处理
app.use((ctx, next) => {
return next().catch(err => {
if (err.status === 401) {
ctx.status = 401;
ctx.body = "Protected resource, use Authorization header to get access\n";
} else {
throw err;
}
});
});
//校验登录
app.use(
koajwt({
secret: cert //秘钥
}).unless({
path: [/\/users\/login/]
}) //unless表示不校验token的url
);
通过 app.use 来调用该中间件,并传入密钥 {secret: ‘my_token’},unless 可以指定哪些 URL 不需要进行 token 验证。token 验证失败的时候会抛出401错误,因此需要添加错误处理,而且要放在 app.use(koajwt()) 之前,否则不执行。
客户端请求需要在header中携带如下请求头
authorization:Bearer token //token为服务器返回的token
更多详情请参考JWT官方网站