繼上次寫了如何優雅的處理異常,這篇講一下如何實現JWT(json web token)認證方式;JWT是一種開放標準(RFC7519),具體的這裏就不重複介紹了,能夠去查看一些說明文檔,這裏就簡單介紹一下egg裏面的應用。javascript
推薦閱讀: 阮一峯的JWT介紹入門html
咱們首先介紹如何本身實現中間件來完成JWT鑑權java
const jsonwebtoken = require('jsonwebtoken');
module.exports = options => {
return async(ctx, next) => {
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();
}
}
複製代碼
// router.js
'use strict';
/** * @param {Egg.Application} app - egg application */
module.exports = app => {
const auth = app.middleware.customAuth();
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/login', controller.home.login);
router.get('/testlogin', auth, controller.home.needLogin);
};
複製代碼
// controller/home.js
'use strict';
const jsonwebtoken = require('jsonwebtoken');
const Controller = require('egg').Controller;
class HomeController extends Controller {
// login接口用於簽名,正常狀況這裏校驗用戶名密碼,這裏demo直接調用sign方法簽名,設置過時時間爲1天
async login() {
const { ctx } = this;
const secret = 'secert';
const token = jsonwebtoken.sign({ key: 'value' }, secret, { expiresIn: '1d' });
ctx.body = { token };
}
// 測試鑑權
async needLogin() {
const { ctx } = this;
ctx.body = '這是驗證過的接口返回的數據';
}
}
module.exports = HomeController;
複製代碼
在測試以前,咱們須要在config.default.js文件中加入下面的代碼,暫時關閉csrf插件(Cross-site request forgery這是一種防止跨站請求僞造安全機制,egg中默認開啓,具體細節能夠去官網查看)web
config.security = {
enable: false,
},
複製代碼
postman調用登陸接口json
postman調用須要鑑權的接口 這裏使用了postman自帶的jwt鑑權方式,同實token從全局變量中獲取 安全
使用現成的koa-jwt來實現鑑權,上一篇已經說了如何引用koa中間件,這裏咱們如今middleware下面建立auth.js文件bash
module.exports = require('koa-jwt');
複製代碼
修改router.js中的中間件引用app
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const auth = app.middleware.auth({ secret: 'secret' });
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/login', controller.home.login);
router.get('/testlogin', auth, controller.home.needLogin);
};
複製代碼
以後進行測試,依然能夠獲得與上述本身編寫一樣的效果;這裏的koa-jwt就是簡化了咱們的代碼,實現了與本身實現的中間件verify相同的功能koa