阅读文档:中文版 | English
更新日志简介:开箱即用的 User authentication template——用户权鉴模板。
适用人群:
前端开发学习egg框架初学者 使用 Vue-egg 架构的开发者 或者像 @yesmore 这样又菜又懒的CV工程师
1.1.1
...
快速开始开始之前,请确保你有以下环境:
Nodejs Npm(Nodejs自带) MySQL 5.7.x git 克隆仓库# git bash $ git clone git@github.com:yesmore/vue-egg-jwt-template.git # or http $ git clone https://github.com/yesmore/vue-egg-jwt-template.git # or release 安装 & 启动
# 为了项目能正常运行,建议先启动后台 $ cd egg-server $ npm i # Start Back-end $ npm run dev $ cd vue-egg-jwt-template $ npm i # Start Front-end $ npm run dev
登录页:
http://localhost:8081/#/login ...Api参考:
http://localhost:7001/jwtlogin http://localhost:7001/jwtmsg http://localhost:7001/init ... 开发者须知此项目基于:
前端框架:Vue 2.5.2
后端框架:Eggjs 2.15.1
数据库:MySQL 2.3.0
文件目录|- 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
// method: Post // Url: http://127.0.0.1:7001/jwtlogin // body: { user:{ username, password } } async doLogin() { let { ctx } = this; try { // 1.Get user-info: username & password let user = ctx.request.body.user; let doUser = await ctx.service.user.getUserByName(user.username); // 2.Check for correctness let oldPsw = await ctx.service.user.getMd5Data(user.password) // Compare the password between web and database if(doUser && (oldPsw === doUser.password)) { let user_jwt = { username: user.username, password: user.password }; // 2.1.Generate token with your user-info & your secret let token = this.app.jwt.sign(user_jwt, this.app.config.jwt.secret); ctx.body = { token: token, status: 200 }; } else { // 2.2.or return error 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
// method: Post // Url: http://127.0.0.1:7001/jwtregister // body: { user:{ username, password, group_id } } async doRegister() { let { ctx } = this; try { // 1.Get user-info: username & password let { user } = ctx.request.body; let { username, password, group_id } = user let doUser = await ctx.service.user.getUserByName(username); // 2.Check for correctness 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 { // 2.2.or return error ctx.body = { msg: 'User already exists.', status: 401 }; } } catch (e) { ctx.body = { msg: 'Server error', status: 501 } } } 加密:md5(crypto)
app/service/user.js
// md5 encryption getMd5Data(pwd) { return crypto.createHash('md5').update(pwd).digest('hex'); } 请求校验中间件:checktoken
app/middleware/checktoken
/** * Token verification Middleware */ checktoken = () => { return async (ctx, next) => { try { // 1.Get token let token = ctx.request.header.token; // 2.Verify 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
// Connect your db(MySQL) config.sequelize = { dialect: 'mysql', database: 'jwttemplate', host: 'localhost', port: 3306, username: 'root', password: '', timezone: '+08:00', }
config/plugin.js
sequelize: { enable: true, package: 'egg-sequelize' }
projectname/app.js
/** * Create db(MySQL) tables * You can understand it as a life cycle */ module.exports = app => { app.beforeStart(async () => { // Be careful: for Dev Environment - Clear db tables after restart server if you set [force] as true! // await app.model.sync({ force: true }); // sync:Create tables from models(/app/model/...) await app.model.sync({}) }) }
用户模型
/** * User model * id: STRING * username: STRING, * password: STRING, * group_id: STRING, * created_at: STRING, * updated_at: STRING */ module.exports = app => { const { STRING } = app.Sequelize; // Serialize converts the first parameter (model name) of define to plural by default // Sequelize默认将define的第一个参数(模型名称)转为复数 const User = app.model.define('user', { username: STRING, password: STRING }); // user's Group: Primary key pointing to group // 主键指向组 User.associate = () => { app.model.User.belongsTo(app.model.Group, { foreignKey: 'group_id', as: 'group' }) } return User }
组模型
/** * Group model * id: STRING * groupname: STRING, * created_at: STRING, * updated_at: STRING */ 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
// Use Eslint Loader? // If true, your code will be linted during bundling and // linting errors and warnings will be shown in the console. useEslint: true, Axios for Vue
我封装了一个 request
工具模块作为独立的http请求模块,位于 vue/src/utils/request.js 中;然后在 vue/main.js 中全局引入并注册到Vue原型上;并且在 vue/config/dev.env.js 文件中设置 baseURL 的开发全局变量 API_ROOT 。这样,在所有页面就可以使用 request
模块发送http
请求。
// request.js import axios from 'axios' const request = axios.create({ baseURL: process.env.API_ROOT // config/ }) // Set the interceptor to carry the token every request request.interceptors.request.use((req) => { let token = localStorage.getItem('token') if (token) { req.headers.token = token } return req }) export default request
// main.js import request from './utils/request.js' Vue.prototype.$http = request
开发选项
// vue/config/dev.env.js module.exports = merge(prodEnv, { NODE_ENV: '"development"', API_ROOT: '"http://127.0.0.1:7001"' })
生产选项
// vue/config/prod.env.js module.exports = { NODE_ENV: '"production"', API_ROOT: '"http://aoau.top:7001"' // 你的服务器 }
// Login.vue this.$http.post('/jwtlogin', { postData })
如果你不需要全局注册 request 模块,可以注释掉 vue/main.js 中的引入语句,并在你需要的页面引入它即可。
// main.js import Vue from 'vue' import App from './App' import router from './router' // import request from './utils/request.js' Vue.config.productionTip = false // Vue.prototype.$http = request /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
// Login.vue <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
版权声明:
1、该文章(资料)来源于互联网公开信息,我方只是对该内容做点评,所分享的下载地址为原作者公开地址。2、网站不提供资料下载,如需下载请到原作者页面进行下载。