VuEgg-jwt-template
阅读文档 :中文版 | English
简介:开箱即用的 User authentication template——用户权鉴模板。
适用人群:
前端开发学习egg 框架初学者
使用 Vue-egg 架构的开发者
或者像 @yesmore 这样又菜又懒的CV 工程师
快速开始
开始之前,请确保你有以下环境:
Nodejs
Npm(Nodejs自带)
MySQL 5.7.x
克隆仓库
1 2 3 4 5 6 $ git clone git@github.com:yesmore/vue-egg-jwt-template.git $ git clone https://github.com/yesmore/vue-egg-jwt-template.git https://github.com/yesmore/vue-egg-jwt-template/releases/tag/v1.0.1-release
安装项目
1 2 3 4 5 6 7 8 9 $ cd vue-egg-jwt-template $ npm i $ npm run dev $ cd egg-server $ npm i $ npm run dev
登录页:
Api参考:
模块
版本
m
v
Vue
2.5.2
egg
2.15.1
egg-jwt
3.1.7
mysql2
2.3.0
文件目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |- egg-server/ |- app/ |- controller/ |- middleware/ |- model/ |- service/ |- view/ |- router.js |- config/ |- config.default.js |- plugin.js |- test/ |- app.js |- package.json |- ... |- vue-egg-jwt-template/ |- build/ |- config/ |- dev.env.js |- index.js |- prod.env.js |- src/ |- assets/ |- router/ |- utils/ |- views/ |- App.vue |- main.js |- static / |- package.json |- ...
交互模型
前端 — (http请求 ) — Contorller — (service ) — MySQL
主要逻辑
用户登陆校验(Jwt ) app/controller/jwt.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 async doLogin ( ) { let { ctx } = this ; try { let user = ctx.request.body.user; let doUser = await ctx.service.user.getUserByName(user.username); let oldPsw = await ctx.service.user.getMd5Data(user.password) if (doUser && (oldPsw === doUser.password)) { let user_jwt = { username: user.username, password: user.password }; let token = this .app.jwt.sign(user_jwt, this .app.config.jwt.secret); ctx.body = { token: token, status: 200 }; } else { ctx.body = { msg: 'Permission verification error! please input correct username or password.' , status: 401 }; } } catch (e) { ctx.body = { msg: 'Server error' , status: 501 } } }
注册用户 app/controller/jwt.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 async doRegister ( ) { let { ctx } = this ; try { let { user } = ctx.request.body; let { username, password, group_id } = user let doUser = await ctx.service.user.getUserByName(username); if (!doUser) { let res = await ctx.service.user.createUser(username, password, group_id) if (res) { ctx.body = { msg: 'User created successfully.' , status: 200 } } else { ctx.body = { msg: 'User created failed.' , status: 402 } } } else { ctx.body = { msg: 'User already exists.' , status: 401 }; } } catch (e) { ctx.body = { msg: 'Server error' , status: 501 } } }
加密:md5 (crypto)app/service/user.js
1 2 3 4 getMd5Data (pwd ) { return crypto.createHash('md5' ).update(pwd).digest('hex' ); }
请求校验中间件:checktoken app/middleware/checktoken
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 checktoken = () => { return async (ctx, next) => { try { let token = ctx.request.header.token; let decode = ctx.app.jwt.verify(token, ctx.app.config.jwt.secret); if (decode.username && decode.password) { await next(); } else { ctx.body = { msg: 'Jwt verification failed' , status: 400 } } } catch (e) { ctx.body = { msg: 'Server error' , status: 501 } } } };
持久化存储:MySQL (sequelize)config/config.default.js
1 2 3 4 5 6 7 8 9 10 config.sequelize = { dialect: 'mysql' , database: 'jwttemplate' , host: 'localhost' , port: 3306 , username: 'root' , password: '' , timezone: '+8:00' , }
config/plugin.js
1 2 3 4 sequelize: { enable: true , package: 'egg-sequelize' }
projectname/app.js
1 2 3 4 5 6 7 8 9 10 11 12 module .exports = app => { app.beforeStart(async () => { await app.model.sync({}) }) }
用户模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 module .exports = app => { const { STRING } = app.Sequelize; const User = app.model.define('user' , { username: STRING, password: STRING }); User.associate = () => { app.model.User.belongsTo(app.model.Group, { foreignKey: 'group_id' , as : 'group' }) } return User }
组模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 module .exports = app => { const { STRING } = app.Sequelize; const Group = app.model.define('group' , { groupname: STRING, }); return Group }
其他配置
ESLint for Vue
此模板默认开启ESlint ,如果你需要关闭,可以执行下面的操作:
config文件夹下的index.js文件中找到useEslint,并改成false
Axios for Vue
我封装了一个 request
工具模块作为独立的http 请求模块,位于 vue/src/utils/request.js 中;然后在 vue/main.js 中全局引入并注册 到Vue原型上;并且在 vue/config/dev.env.js 文件中设置 baseURL 的开发全局变量 API_ROOT 。这样,在所有页面就可以使用 request
模块发送http
请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import axios from 'axios' const request = axios.create({ baseURL: process.env.API_ROOT }) request.interceptors.request.use((req ) => { let token = localStorage .getItem('token' ) if (token) { req.headers.token = token } return req }) export default request
1 2 3 4 import request from './utils/request.js' Vue.prototype.$http = request
1 2 3 4 5 module .exports = merge(prodEnv, { NODE_ENV: '"development"' , API_ROOT: '"http://127.0.0.1:7001"' })
1 2 this .$http.post('/jwtlogin' , { postData })
如果你不需要全局注册 request 模块,可以注释掉 vue/main.js 中的引入语句,并在你需要的页面引入它即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false new Vue({ el: '#app' , router, components: { App }, template: '<App/>' })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script> import request from '../utils/request.js export default { data () { return { data: ' ' } }, methods: { async fetchDate () { let res = await request.get(' /jwtmsg') this.data = res.data } } } </script>
License
MIT
Tips:
Please indicate the source and original author when reprinting or quoting this article.