1、数据库设置
// 用户表
const userSchema = new Schema({
name: String,
password: String,
phone:{
type:String,
default:"15232232001"
},
email:{
type:String,
default:"excellent@qq.com"
},
imgUrl: String,
status:{
type:String,
default:"已激活"
}, // 角色表的外键
rid: {
type: mongoose.Types.ObjectId,
ref:'role'
},
})
// 权限表
const menuSchema = new Schema({
authname:String,
level:Number,
path:String,
pid:{ // 自关联
type:mongoose.Types.ObjectId,
default:null
}
})
// 角色
const roleSchema = new Schema({
rolename:String,
desc:String,
})
// 关联表
const role_menuSchema = new Schema({
roleid:{
type:mongoose.Types.ObjectId,
ref:'role'
},
menus:[
{
type:mongoose.Types.ObjectId,
ref:'menu'
}
]
})
2、jwt的token配置app.js
// token配置
const expressJWT = require("express-jwt")
app.use(expressJWT({
//解析口令 需要和加密的时候保持一致
secret : "feng",
//加密方式 SHA256 加密方式在express-jwt 里面叫做 HS256
algorithms : ["HS256"]
}).unless({
//不需要验证token 的路径标识(下面的路由不需要进行token验证)
path:['/upload','/reg','/login']
}))
3、登录时的token验证,以及获取权限的列表
router.post('/login', async (req, res) => {
let info = req.body
// 根据用户名密码找出用户信息(角色_id)
let istrue = await usersModel.find({ $and: [{ name: info.name }, { password: info.pass }] })
if (istrue.length < 1) {
res.send({
code: 404
})
return false
}
let data = await usersModel.find({ $and: [{ name: info.name }, { password: info.pass }] }).populate("rid").lean()
// 根据角色的_id找到,角色对应的权限
let quandic = await role_menuModel.find({ roleid: data[0].rid['_id'] }).populate(["menus", "roleid"]).lean()
let role = quandic[0].roleid.rolename
// 将找出来的权限排列成树状
let cates = quandic[0].menus
let quan = []
let quanObj = {}
cates.forEach(item => {
quanObj[item._id] = item
})
cates.forEach(item => {
if (!item['pid']) {
quan.push(item)
} else {
if (!quanObj[item['pid']]['children']) {
quanObj[item['pid']]['children'] = []
}
quanObj[item['pid']]['children'].push(item)
}
})
let token = "Bearer " + jwt.sign(info, 'feng', { expiresIn: "1h" })
res.send({
code: 200,
msg: '登陆成功',
token,
data,
quan,
role
})
})
4、vue2前端-axios请求拦截器
// main.js文件
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = 'http://localhost:3000/'
/* axios请求拦截器,发送请求时,首先判断是否有Token 如果有,就统一设置authorization */
axios.interceptors.request.use(item => {
let token = sessionStorage.getItem('token')
if (token) {
item.headers.authorization = token
}
return item
})
/*
请求:let {data:{data,quan}} = await this.$axios.post('login',ruleForm)
*/
5、vue2前端-路由守卫(不进行登录不能访问路由)
// router.js文件
router.beforeEach((to,from,next)=>{
if(to.name == 'reg') return next()
// home是登录页面
if(to.name != 'home'){
let token = window.sessionStorage.getItem('token')
if(!token){
next('home')
}
}
next()
})
6、vue2-菜单进行动态渲染
async createlist(){
let ruleForm = JSON.parse(sessionStorage.getItem('msg')) // 注册方面的用户信息
let {data:{data,quan}} = await this.$axios.post('login',ruleForm)
this.msg = data[0]
this.quanlist = quan
},
<el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
background-color="#545c64" :unique-opened="true" text-color="#fff" active-text-color="#ffd04b">
<!-- (2) -->
<el-submenu v-for="(item) in quanlist" :index="item._id">
<template slot="title">
<i class="el-icon-message-solid"></i>
<span >{{item.authname}}</span>
</template>
<el-menu-item-group v-for="it in item.children">
<router-link class="el-icon-menu" :to="{ name: it.path ,params:{role:$route.params.role}}" tag="el-menu-item">
{{it.authname}}
</router-link>
</el-menu-item-group>
</el-submenu>
</el-menu>