node中使用crypto生成token
# node 中使用 crypto 生成 token
参考:https://www.jianshu.com/p/109ed0006e2f
# crypto 安装
npm install crypto-js
# crypto 使用
# 完整项目地址
- 可以访问我的
gitbub项目:(趣学)https://github.com/coderlyu/quxue - 该项目的
server文件夹就是express搭建的服务器 - 里面的
utils文件夹下的token.js就是token生成和验证的地方 - 具体如何使用,可以找到用户登录的地方,返回结果有 生成
token的使用 - 在需要验证
token的地方,使用了自定义中间件,位于utils文件夹的index.js里面的autotoken方法
# 创建 token
const secret = "coderly.cn";
createToken: function (payload) {
let obj2 = {
data: payload, // payload
created: parseInt(Date.now() / 1000), // token生成的时间的,单位秒
// exp: parseInt(timeout) || 10 // token有效期 单位是秒
exp: 7 * 24 * 60 * 60 // 7天过期
};
// payload信息
let base64Str = Buffer.from(JSON.stringify(obj2), "utf8").toString(
"base64"
);
// 添加签名,防篡改
let hash = crypto.createHmac("sha256", secret);
hash.update(base64Str);
let signature = hash.digest("base64");
return base64Str + "." + signature;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
【说明】
- 传入的
payload参数就是我们需要加密的 内容,比如说我们可以将用户账号、密码作为payload加密到token里面,这样我们解密的时候就可以直接获取到用户的信息,来验证是否存在该用户以及该用户是否有权限访问等信息 - 我使用的是
hmac(密钥哈希),所以我们需要一个密钥, 在这里是secret存储的字符串 let hash = crypto.createHmac("sha256", secret);表示创建一个hmac密钥哈希,它需要传入两个参数,第一个参数使用sha系列加密,它可以是SHA-1:sha1、SHA-2:sha256、SHA-1:sha512,SHA-1已经被破解,SHA-3应用较少,目前应用广泛相对安全的是SHA-2算法,所以本次讲的是SHA-2;第二个参数是加密的密钥hash.update(base64Str);表示 需要加密的内容是base64Strhash.digest("base64");表示字符编码是base64,如果不设置,默认字符串编码为UTF-8
# 获取 token 信息
const secret = "coderly.cn";
decodeToken: function (token) {
let decArr = token.split(".");
if (decArr.length < 2) {
// token不合法
return false;
}
let payload = {};
// 将payload json字符串 解析为对象
try {
payload = JSON.parse(Buffer.from(decArr[0], "base64").toString("utf8"));
} catch (e) {
return false;
}
// 检验签名
let hash = crypto.createHmac("sha256", secret);
hash.update(decArr[0]);
let checkSignature = hash.digest("base64");
return {
payload: payload,
signature: decArr[1],
checkSignature: checkSignature
};
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 检验 token 是否过期
checkToken: function (token) {
let resDecode = this.decodeToken(token);
if (!resDecode) {
return false;
}
// 是否过期
let expState =
parseInt(Date.now() / 1000) - parseInt(resDecode.payload.created) >
parseInt(resDecode.payload.exp)
? false
: true;
if (resDecode.signature === resDecode.checkSignature && expState) {
return true;
}
return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上次更新: 2021/09/13, 15:11:59