JWT的三部分
- Header:一般包括两个部分,使用的加密算法和token的类型。这一部分用Base64Url编码之后作为JWT的第一部分
{
"alg": "HS256",
"typ": "JWT"
}
Payload:The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.这一部分用Base64Url编码之后作为JWT的第二部分
Signature: 用encoded header, the encoded payload, a secret, the algorithm specified in the header计算出一个签名,作为第三部分
JWT加密中的几种算法
HS256
HS256的全称是HMAC+SHA256.
- HS256的签名过程:将密钥、Header、Payload三者一起用HS256算法计算出一个hash值作为签名。
- HS256的验证过程:将密钥、Header、Payload三者一起用HS256算法计算出一个hash值,然后比较这个hash值和signature,如果一样说明这个签名是有效的。
HS256加密的缺点:
- 如果要更改密钥,那么所有的服务器上面的密钥都要更改,不方便
RS256
RS256的全称是RSA+SHA256
- RS256的签名过程:把Header和Payload先用SHA256计算出一个hash值(因为有的时候Payload比较长,直接用RSA会耗费过多的时间,于是先用SHA256计算出一个较短 的hash值),然后用私钥给这个hash值签名得到jwt的第三部分signature。
- RS256的验证过程:把Header和Payload先用SHA256计算出一个hash值(Header和Payload是Base64Url编码的,并没有进行任何密码学上的处理),再用公钥对signature进行RSA解密,如果解密出来的结果和先前计算出的hash值一样,说明这个jwt是有效的。
RS256加密的优点:更改私钥更容易,只需要在发签名的服务器上面更改私钥就可以了。
在KOA中调用接口的实现(HS256)
在登录接口分发token:
async login(ctx){
/*这里缺乏参数检查*/
const user = await User.findOne(ctx.request.body);
if(!user) {
ctx.throw(401, "用户名或者密码错误");
}
const {_id, name} = user;
/*用jsonwebtoken算出jwt签名,然后传递给前端*/
const token = jsonwebtoken.sign({_id, name}, secret, {expiresIn: "1d"});
console.log(token);
ctx.body = {token};
}
在接受请求时认证token
const auth = async (ctx, next) => {
console.log("here");
const {authorization=""} = ctx.request.header;
const token = authorization.replace("Bearer ", "");
try{
const user = jsonwebtoken.verify(token, secret);
ctx.state.user = user;
}catch(err){
ctx.throw(401, err.message);
}
await next();
}
也可以用koa-jwt组件
const jwt = require("koa-jwt");
const auth = jwt({secret});