最近做的项目是通过单点登录入口进入自己的项目首页,大概总结一下思路:
1. 新建一个ssoUrl.js 文件:
2.跟main.js 同级新建一个permission.js(文件名称随意),然后在main.js 文件中导入:
permission.js :
import router from './router'
import store from './store'
import Cookies from 'js-cookie'
import {
Message,
MessageBox
} from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import {
getToken,
setToken,
setExpiresIn,
removeToken,
setUsername,
setNickname,
setAdminType,
setAdminSex
} from '@/utils/auth'
import {
setCookie,
delCookie,
getCookie
} from '@/utils/cookie.js'
import {
projectUrl
} from "@/config/ssoUrl";
import {
ssoLogin,
ssoLogOut
} from "@/api/common";
// 获取地址栏tiket
function getTicket() {
let ticket;
let url = location.hash; //获取url中"#"符后的字串
let theRequest = {};
if (url.indexOf("?") != -1) {
let str = url.substr(3);
let strs = str.split("&");
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
}
}
ticket = theRequest.ticket;
return ticket
}
NProgress.configure({
showSpinner: false
})
const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
router.beforeEach((to, from, next) => {
// NProgress.start()
let ticket = getTicket()
console.log('ticket', ticket)
console.log('projectUrl', projectUrl)
console.log('域名', window.location.origin)
console.log(store.getters.roles)
if (window.location.origin == 'https://okr.sk.com') {
if (getToken()) {
if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', {
roles
}).then(accessRoutes => {
sessionStorage.setItem('accessRoutes', JSON.stringify(accessRoutes))
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({
...to,
replace: true
}) // hack方法 确保addRoutes已完成
})
})
}else {
next()
}
} else {
if (ticket) {
ssoLogin({
ticket
}).then(res => {
if (res.code === 200) {
sessionStorage.setItem('sex', res.data.sex)
// localStorage.setItem('access_token', res.data.access_token)
// localStorage.setItem('expires_in', res.data.expires_in)
// localStorage.setItem('nick_name', res.data.nick_name)
// localStorage.setItem('user_name', res.data.user_name)
// localStorage.setItem('type', res.data.type)
setToken(res.data.access_token)
store.commit('SET_TOKEN', res.data.access_token)
setExpiresIn(res.data.expires_in)
store.commit('SET_EXPIRES_IN', res.data.expires_in)
setNickname(res.data.nick_name.trim())
store.commit('SET_NICK_NAME', res.data.nick_name.trim())
setUsername(res.data.user_name.trim())
store.commit('SET_USER_NAME', res.data.user_name.trim())
setAdminType(res.data.type.trim())
store.commit('SET_TYPE_LEVEL', res.data.type.trim())
setAdminSex(res.data.sex)
store.commit('SET_USER_SEX', res.data.sex)
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', {
roles
}).then(accessRoutes => {
sessionStorage.setItem('accessRoutes', JSON.stringify(accessRoutes))
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({
...to,
replace: true
}) // hack方法 确保addRoutes已完成
location.hash = '#/'
})
})
} else {
sessionStorage.clear()
localStorage.clear()
MessageBox.confirm(
'系统当前没有该用户,请联系okr@111shuke.com',
'系统提示', {
confirmButtonText: '确定',
closeOnClickModal: false,
showCancelButton: false,
showClose: false,
type: 'warning'
}
).then(() => {
Cookies.remove("sso_sessionid")
location.hash = "#/"
location.href = 'https://home.sk.com/#/';
})
}
}).catch(err => {
console.log(err)
sessionStorage.clear()
localStorage.clear()
location.href = projectUrl;
})
} else {
sessionStorage.clear()
localStorage.clear()
location.href = projectUrl;
}
}
} else {
if (getToken()) {
/* has token*/
if (to.path === '/login') {
next({
path: '/'
})
NProgress.done()
} else {
if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', {
roles
}).then(accessRoutes => {
// 测试 默认静态页面
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({
...to,
replace: true
}) // hack方法 确保addRoutes已完成
})
})
.catch(err => {
store.dispatch('FedLogOut').then(() => {
Message.error(err)
next({
path: '/login'
})
})
})
} else {
next()
}
}
} else {
// 没有token
if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入
next()
} else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
NProgress.done()
}
}
}
})
// router.afterEach(() => {
// NProgress.done()
// })
permission.js 中有动态获取菜单的接口,可根据项目需求添加或者删除
3.在store文件夹中有一个获取动态路由的js文件:
代码:
import { constantRoutes } from '@/router'
import { getRouters } from '@/api/menu'
// import Layout from '@/layout/index'
const permission = {
state: {
routes: [],
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
const accessedRoutes = filterAsyncRouter(res.data)
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) {
return asyncRouterMap.filter(route => {
if (route.component) {
// Layout组件特殊处理
if (route.component === 'Layout') {
// route.component = Layout
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
}
export const loadView = (view) => { // 路由懒加载
return (resolve) => require([`@/views/${view}`], resolve)
}
export default permission