實現一套基於jwt方案的單點登陸系統,能夠用於平時自身接外包作項目。javascript
1.eggjs基於koa2
,能夠認爲是koa2的框架層面的約束,須要有koa2基礎,能夠參考koa2文檔
2.關於koa2洋蔥圈模型的解析能夠看這裏
3.node版本8.x
,能夠很方便地使用async/await來寫異步代碼
4.egg.js官方文檔html
官方文檔推薦傳送門,不過咱們用不到這麼多,一切以需求爲主,只介紹用的到的地方,其餘的功能能夠之後慢慢摸索前端
├── package.json ├── app | ├── router.js │ ├── controller │ | └── user.js │ ├── service │ | └── user.js │ ├── middleware │ | └── checkToken.js │ └── model │ └── user.js ├── config | ├── plugin.js | ├── config.default.js
以上就是框架約定的目錄,因爲咱們前端分離,因此view目錄也不須要了:java
修改plugin.js
node
exports.cors = { enable: true, package: 'egg-cors', }
修改config.default.jsgit
exports.security = { csrf: { enable: false, ignoreJSON: true }, domainWhiteList: ['*'] } exports.cors = { origin: '*', allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH' }
安裝請看redis在mac下的安裝,其餘操做系統請根據口味自行百度。github
使用請參考egg-redis文檔web
Redis是什麼redis
yarn add egg-redis
修改plugin.js
sql
exports.redis = { enable: true, package: 'egg-redis', }
修改config.default.js
exports.redis = { client: { port: [port], host: '127.0.0.1', password: [password], db: 0 } }
必定要改默認端口!必定要改默認端口!必定要改默認端口!
請看:Redis 未受權訪問缺陷可輕易致使系統被黑,請修改redis.conf: requirepass
(密碼) , port
(端口)MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.
解決方案是修改redis.conf: stop-writes-on-bgsave-error
改成no
安裝請看postgresql在mac下的安裝,其餘操做系統請根據口味自行百度。
使用請參考egg-sequelize文檔
PostgreSQL 與 MySQL 相比,優點何在?
yarn add egg-sequelize yarn add pg pg-hstore
修改plugin.js
exports.sequelize = { enable: true, package: 'egg-sequelize' }
修改config.default.js
exports.sequelize = { dialect: 'postgres', database: 'postgres', host: 'localhost', port: '8888', username: 'postgres', password: '123456' }
yarn add jsonwebtoken
var jwt = require('jsonwebtoken'); var tokenKey = 'token key' var token = jwt.sign({ foo: 'bar' }, tokenKey); var decoded = jwt.verify(token, tokenKey); console.log(decoded.foo) // bar
egg.js是基於Koa2的,能夠很是容易的引入 Koa 中間件生態。
在咱們這個應用中,不是全部的請求都須要驗證token,因此能夠經過中間件來處理,下面咱們就來寫一箇中間件。
app/model/checkToken.js
const { verify } = require('jsonwebtoken') const moment = require('moment') module.exports = options => { return async function checkToken(ctx, next) { const { jwtKey } = ctx.app.config.appConfig const {request: { path, header: {token} }} = ctx const {exclude=[]} = options let decodedJwt = {} try { if (exclude.indexOf(path.replace('/', '')) === -1) { // 須要token的接口 decodedJwt = verify(token, jwtKey) // token exp 超時 if(moment().isAfter(decodedJwt.exp)) { throw { code: -340, msg: 'token 過時' } } } else { //不須要token的接口 decodedJwt.exp = -1 } } catch (error) { ctx.app.logger.error('token error', error) if (error.code) { ctx.body = error } else { ctx.body = { code: -360, msg: 'token 錯誤' } } } if (decodedJwt.exp) { await next() } } }
修改config.default.js
exports.middleware = ['checkToken'] // 中間件會按順序執行 // 中間件須要的配置項,能夠經過app.config[${middlewareName}]訪問 exports.checkToken = { exclude: ['login', 'signup'] }