实现一套基于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'] }