- 首先看当前环境:
"dependencies": {
"egg": "^3",
"egg-cors": "^2.2.3",
"egg-jwt": "^3.1.7",
"egg-scripts": "^2",
"egg-sequelize": "^6.0.0",
"egg-view-nunjucks": "^2.3.0",
"mysql2": "^2.3.3",
"utility": "^1.17.0"
},
- 然后, 我是通过openssl生成的私钥和公钥
openssl
> genrsa -out private.key 1024
> rsa -in private.key -pubout -out public.key
- 然后在config.default.js中配置一下egg-jwt插件:
'use strict';
/**
* @param {Egg.EggAppInfo} appInfo app info
*/
// 通过fs文件系统读取私钥中的内容
const fs = require('fs');
const path = require('path');
// 绝对路径写法:拿到当前文件所在的文件目录和key文件所在的文件目录进行拼接
const PRIVATE_KEY = fs.readFileSync(
path.resolve(__dirname, '../app/keys/private.key')
);
...
// jwt鉴权配置
config.jwt = {
secret: PRIVATE_KEY // 赋值给token的加密的密钥
};
- 然后在plugin.js中开启egg-jwt插件:
jwt: {
enable: true,
package: 'egg-jwt'
}
- 在login的controller中使用jwt颁发token:
'use strict';
const { Controller } = require('egg');
class LoginController extends Controller {
async index() {
const { ctx, app } = this;
const { id, name } = ctx.user;
console.log(id, name);
const token = app.jwt.sign({ id, name }, app.config.jwt.secret, {
// 设定当前token失效时间(单位:秒),当前设定的是24个小时
expiresIn: 60 * 60 * 24,
// 指定当前token的加密方式为RS256
algorithm: 'RS256'
});
ctx.body = {
id,
name,
token
};
}
}
module.exports = LoginController;
注意了,坑就是在这个地方,由于网上很多都是在配置egg-jwt插件时,给secret属性直接赋值一个固定的字符串,而没有从某个文件中读取过内容再赋值。所以我就按照网上的这种方式去使用,可是结果就是,总是出现代码500的报错,并提示 callback is not a function !报错位置在:
const token = app.jwt.sign({ id, name }, app.config.jwt.secret, {
// 设定当前token失效时间(单位:秒),当前设定的是24个小时
expiresIn: 60 * 60 * 24,
// 指定当前token的加密方式为RS256
algorithm: 'RS256'
});
我在网上找了很多帖子都没找到解决的办法,最后我发现egg-jwt这个插件和原本的jwt库封装的sign()方法是不相同的:
- jwt库中的sign方法中secret参数可传递的数据类型可以是string或者Buffer
- 而egg-jwt中的sign方法中secret参数可传递的数据类型只能是string
而我之前在config.default.js中配置egg-jwt插件时,读取私钥获取到的数据为Buffer,所以原因找到了,是因为我参数传递错误导致的,所以我将config.default.js中读取私钥的时候,增加了一个‘utf-8’这个参数,保证我拿到的PRIVATE_KEY是一个字符串,问题解决: