创建一个 egg 新项目,我这里创建的是 TypeScript 的模式
npm init egg --type=ts
npm install
创建完成并安装完初始化依赖文件后需要再次安装两个包
1.egg-cors
跨域包
2.egg-jwt
token生成以及验证包
npm install egg-cors egg-jwt --save
安装完成后在根目录下的 config/plugin.ts
配置一下,如:
import { EggPlugin } from 'egg';
const plugin: EggPlugin = {
jwt: {
enable: true,
package: "egg-jwt"
},
cors: {
enable: true,
package: 'egg-cors',
}
};
export default plugin;
接下来在 config/config.default.ts
里面继续配置:
config.jwt = {
secret: "123456"//自定义 token 的加密条件字符串
};
config.security = {
csrf: {
enable: false,
ignoreJSON: true
},
domainWhiteList: ['http://localhost:8080'],//允许访问接口的白名单
};
config.cors = {
origin:'*',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
};
最后一步操作,也是 TypeScript
独有的坑,需要在根目录下的 typings/index.d.ts
文件里声明一个 any
类型,否则会类型错误:
import 'egg';
declare module 'egg' {
interface Application {
jwt: any;
}
}
好了以上配置完成后就开始接下来的核心操作了。
首先我在根目录下的 app/router.ts 创建访问路由:
import { Application } from 'egg';
export default (app: Application) => {
const { controller, router, jwt } = app;
//正常路由
router.post('/admin/login', controller.admin.login);
/*
* 这里的第二个对象不再是控制器,而是 jwt 验证对象,第三个地方才是控制器
* 只有在需要验证 token 的路由才需要第二个 是 jwt 否则第二个对象为控制器
**/
router.post('/admin',jwt, controller.admin.index);
};
接下来我去编写我的控制器,在根目录下的 app/controller/home.ts
编写内容:
import { Controller } from 'egg';
export default class AdminController extends Controller {
// 验证登录并且生成 token
public async login() {
const { ctx ,app} = this;
//获取用户端传递过来的参数
const data = ctx.request.body;
// 进行验证 data 数据 登录是否成功
// .........
//成功过后进行一下操作
//生成 token 的方式
const token = app.jwt.sign({
username: data.username, //需要存储的 token 数据
//......
}, app.config.jwt.secret);
// 生成的token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1NjAzNDY5MDN9.B95GqH-fdRpyZIE5g_T0l8RgzNyWOyXepkLiynWqrJg
// 返回 token 到前端
ctx.body = token;
};
//访问admin数据时进行验证token,并且解析 token 的数据
public async index() {
const { ctx ,app} = this;
console.log(ctx.state.user);
/*
* 打印内容为:{ username : 'admin', iat: 1560346903 }
* iat 为过期时间,可以单独写中间件验证,这里不做细究
* 除了 iat 之后,其余的为当时存储的数据
**/
ctx.body = {code:0,msg:'验证成功'};
}
}
前端请求的时候需要在 headers
里面上默认的验证字断 Authorization
就可以了,如:
axios({
method: 'post',
url: 'http://127.0.0.1:7001/admin',
data: {
username: 'admin',
lastName: '123456'
},
headers:{
// 切记 token 不要直接发送,要在前面加上 Bearer 字符串和一个空格
'Authorization':`Bearer ${token}`
}
}).then(res=>{
console.log(res.data)
})
网上大部分 egg 验证 token 的教程都不讲验证方法和过程,只是光顾讲 webjsontoken 的原理特别不适合新手,本人也是踩坑过多,终于成功后写下的结论,希望帮助有需要的人。
好了,踩坑结束。