# 文章目录
本文介绍怎么使用 jsonwebtoken 库实现基于非对称加密算法的 token 认证。
文末有完整源码。
# 一、Token 的组成
JWT 生成的 Token 由三部分组成:
header
- alg:采用的加密算法,默认是 HMAC SHA256(HS256),采用同一个密钥进行
加密和解密; - typ:JWT,固定值,通常都写成 JWT 即可;
- 会通过 base64Url 算法进行编码;
payload
- 携带的数据,比如我们可以将用户的 id 和 name 放到 payload 中;
- 默认也会携带 iat(issued at),令牌的签发时间;
- 我们也可以设置过期时间:exp(expiration time);
- 会通过 base64Url 算法进行编码
signature
- 设置一个 secretKey,通过将前两个的结果合并后进行 HMACSHA256 的算法;
- HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);
- 但是如果 secretKey 暴露是一件非常危险的事情,因为之后就可以模拟颁发 token,也可以解密 token;
# 二、生成私钥和公钥
以下操作需要 openssl
协议支持,mac
系统自带,windows
使用Git Bash Here
# 3.1 生成私钥
会在当前目录生成一个 private.key
的私钥
genrsa \-out private.key
# 3.2 根据私钥生成公钥
会在当前目录生成一个 public.key
的私钥
rsa \-in private.key \-pubout \-out public.key
# 三、实现基于非对称加密的 token 认证
完整源码:
index.js
const Koa = require("koa");
const Router = require("koa-router");
const jwt = require("jsonwebtoken");
const fs = require("fs");
const app = new Koa();
const testRouter = new Router();
// 注意:在项目中的任何一个地方的相对路径,都是相对于 process.cwd
const PRIVATE_KEY = fs.readFileSync("./keys/private.key");
const PUBLIC_KEY = fs.readFileSync("./keys/public.key");
// 登录接口
testRouter.post("/register", (ctx, next) => {
const user = { id: 110, name: "why" };
// 这里能拿到 颁发的token
const token = jwt.sign(user, PRIVATE_KEY, {
expiresIn: 120, //过期时间 单位:s
// 指定加密算法 RS256=>非对称加密(安全,速度不及HS256) HS256=>对称加密(不及RS256安全,但速度快)默认
algorithm: "RS256",
});
ctx.body = token;
});
// 验证接口
testRouter.post("/login", (ctx, next) => {
const authorization = ctx.headers.authorization;
const token = authorization.replace("Bearer ", "");
console.log("token: ", token);
try {
// 验证token
const result = jwt.verify(token, PUBLIC_KEY, {
// 指定了什么加密,则用什么解密,可以指定多个解密算法
algorithms: ["RS256"],
});
// 验证不通过或失败会抛出异常
ctx.body = `验证结果:${JSON.stringify(result)}`;
} catch (error) {
ctx.body = `Token无效:${error}`;
}
});
app.use(testRouter.routes());
app.use(testRouter.allowedMethods());
app.listen(8000, () => {
console.log("start");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
private.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvYySUOyU4OKAgN0sF7XSSCnNXUMAPuI3wFKRYowl34eaAgBm
cXpqNmhucwmWeyv6hh2mddGw/dK7EqJYDd3NSyFKAGXVGj4IMUqpRQFcL8WICTKL
fY2S1aO+MHAgUZZtVjvk6e//ygv+/LOJfBlV8DbxCaiBpjiCUlIC01bg2lOhY8BP
9JZyqjD+Nricz50YLRZjltCepJu2meSOEdD0siP6xoKbML043L0xr3/sqTKt8Hz+
yuqw5lgIxH5TDKYzM+8Rz76lyEy15SQ/V9QTXmnQ6ZTH9lJCNA6i7rNVe5OfvBkb
f/vLdy91Hmrj9/Om4BSy92s4cKkpiWZIW19pSwIDAQABAoIBAAYrThPOL2ZGWPJY
wHehFk/89E8lwBtL146t4Ud40j69Nhj8lFj7J/vPWFDsLfaiTswQqPtKsN0B/86y
c/U3k9fvJG5w4gexnyijinDRg4OWhT/vYjTa572GT8lZzON65uIYnvGyOvwDefAV
k9LzLCXeU+gBkP6s9ijhvG/OcxEH+1ATCSI3b/DNpKCEd1YG0y9mZYKxzqRDJLL2
4OzdM+n6tugYNZy4smE0AQMpKsNtyp2yhyEv4CcZSIQ+DYxnCgtHYsIRudHyDlaP
3X5LyBoCSKsS1YT+nJiYhGowSgmXee6uo2ny0Nw+J5WII+uv/cCazxrOTZMBQxHO
3SiSsmkCgYEA+8jeDUQsAs1SiTHrD23R2MhHH4wS2jB0EqCkdeuP8pajPG1ZKpXX
b9+WuF7e1a1K5fZYmGgBUOd30pWG0A0s/CgZ+5Dti5KYrRsq0hBB0fvV/8op9XJx
2jVKnaIQVIyKfw+S5BIGLmQId9HS3yzhSOOmAXQBzqykqlQ6zXaN21cCgYEAwLj3
epZsVqFFBYCH9X/HgGq9oj7pSzn4t8OIW97yiugt8b0+W7rn0DO2eHR+Sx7iX/tx
8+w2YuEPEKytmvJw4VCNMPR3lOiLy0Pjk6qNxFnFEDWuM6GBZoexiVr0WWbfaxEI
ELaLD1NcTG3fQWxjNPz3EdCI7rWijXtEztrBHS0CgYEAlzVUlWcBf1VLYfVGk2eC
hMwSWpHGqJ48twseeWrUcf2hXqLUz8xZK2h9nY/sByshNeWx4yVi1PGNdjwyUDP5
dh2nLPsmjZGmex87ohf9T1wMcqc4d50ZXtBuVSiE4iHc8t2pe6qPZ8DPjRXHrBvJ
1/pPMcQ3aaUo5tnazpWKL9UCgYA/WQ1P6D34Q85SPqtyEOxc07k9qXw50/ZjQQyD
VkdXTXY8rb3fnRIxp63k7jXNL3utnRMZ4J0H535yNrBh7CsahMXEP7dG5SF+UPRv
R3KOBgv2hg6avg2wzA2ZXqJO+Lebk9+Yzsfq47XFEaB++sepVTVJT8iS3nVuGATI
EbPEiQKBgQCaW9oaP9sZkmOcVSRi9r7PdrlLggBsrfOCQNfMAzuEDV3T9J9+1pDR
qZeo+Gue/rYeWtmyhiGchM4AeJkhicMdYfuDwliZxbeBptzqcbXSIAifTq9X4e45
FgaF7aEWUnqRWjSoMFRjN+B5MBrrdOnAaaK+cAGa9SCUU4/hgPUgbA==
-----END RSA PRIVATE KEY-----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYySUOyU4OKAgN0sF7XS
SCnNXUMAPuI3wFKRYowl34eaAgBmcXpqNmhucwmWeyv6hh2mddGw/dK7EqJYDd3N
SyFKAGXVGj4IMUqpRQFcL8WICTKLfY2S1aO+MHAgUZZtVjvk6e//ygv+/LOJfBlV
8DbxCaiBpjiCUlIC01bg2lOhY8BP9JZyqjD+Nricz50YLRZjltCepJu2meSOEdD0
siP6xoKbML043L0xr3/sqTKt8Hz+yuqw5lgIxH5TDKYzM+8Rz76lyEy15SQ/V9QT
XmnQ6ZTH9lJCNA6i7rNVe5OfvBkbf/vLdy91Hmrj9/Om4BSy92s4cKkpiWZIW19p
SwIDAQAB
-----END PUBLIC KEY-----
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9