1.在前置路由这块判断是否是第三方登录 如果是第三方的话有哪些依据 我这里是window进行的跳转 所以使用的是window.location.href去获取的
// 判断是否有ceeess_token
let hrefIdx = window.location.href.indexOf('access_token=')
2.如果有的话 就根据后端给的接口发请求获取后端返回给我们的token 和用户信息ueser
因为是写在前置路由这里的 axios是异步请求 所以我这里使用了promise 为了能够及时拿到后端返回的信息
if(hrefIdx>-1){
new Promise((resolve)=>{
api.login.noThirdLogin({'access_token':acc_token}).then((res)=>{
})
})
}
3.在axios的拦截器这边 判断如果没有token的话 路由是要重新定位到登录页面的
所以在这里我们发完请求 拿到后端返回的token 和用户信息之后 我们要及时的把token 和user 放在cookies中(因为我们是使用的cookies进行的存储 如果你们是内存的话 也同理 也要放入内存中) 当然 我们需要进行一个判断 如果第三方原本就有cookies的话 我们首先要清除 之后在重新添加进去(我突然不确定有没有必要了) 如果没有的话 就直接把我们拿到的信息 给放进去就可以 千万记得在拿到token和user之后要及时的放入cookies(如果你们在axios拦截器中有判断token是否存在的 就千万不要忘记 不然会一直跳转登录页面 进而卡死的)
// 第三方登录
if(hrefIdx>-1){
store.commit('menuRouteLoaded', false)
new Promise((resolve)=>{
api.login.noThirdLogin({'access_token':acc_token}).then((res)=>{
if(res.code=200 && res.data.token && res.data.principal){
if(Cookies("token") && Cookies("user")){
Cookies.remove('token')
Cookies.remove('user')
Cookies.set('token', res.data.token) // 放置token到Cookie
Cookies.set('user', res.data.principal) // 放置user到Cookie
next({ path: '/' })
}else{
Cookies.set('token', res.data.token)
Cookies.set('user', res.data.principal)
next({ path: '/' })
}
}
})
})
}
3.这个地方为什么使用next({path:'/'})呢?当然是因为使用next()的话他不会直接走呀 因为我们在后面是又进行了判断是否有token 如果都满足之后我们会进行加载动态的路由和菜单的。如果这一步我们直接next() 他会进去 但是菜单什么的就不会显示 因为他没有加载 所以第三方登录的话 拿到信息之后第一步我们就进行存储信息就好 之后我们给他定位至首页 他会走下面的判断 然后会进行加载动态路由 // 加载动态菜单和路由 addDynamicMenuAndRoutes(userName, to, from) 这时候就可以完整的显示了
完整代码:
index.js
router.beforeEach((to, from, next) => {
// 因为我们有不同的账户 不同的账户现在的菜单不一致 这边是进行用户菜单进行重新加载的 如果不进行加载的话 第三方进入之后会默认显示上次我们登陆的用户的菜单
store.commit('menuRouteLoaded', false)
// 登录界面登录成功之后,会把用户信息保存在会话
let hrefIdx = window.location.href.indexOf('access_token=')
let acc_token = window.location.href.slice(hrefIdx + 13)
// 第三方登录
if(hrefIdx>-1){
store.commit('menuRouteLoaded', false)
new Promise((resolve)=>{
api.login.noThirdLogin({'access_token':acc_token}).then((res)=>{
if(res.code=200 && res.data.token && res.data.principal){
if(Cookies("token") && Cookies("user")){
Cookies.remove('token')
Cookies.remove('user')
Cookies.set('token', res.data.token) // 放置token到Cookie
Cookies.set('user', res.data.principal) // 放置user到Cookie
Cookies.set('theme', res.logContent.theme) // 放置theme到Cookie
next({ path: '/' })
}else{
Cookies.set('token', res.data.token)
Cookies.set('user', res.data.principal)
Cookies.set('theme', res.logContent.theme)
next({ path: '/' })
}
}
})
})
}
let token = Cookies.get('token')
let userName = Cookies.get('user')
if (to.path === '/login') {
// 如果是访问登录界面,如果用户会话信息存在,代表已登录过,跳转到主页
if(token) {
next({ path: '/' })
} else {
next()
}
}else {
if (!token) {
next({ path: '/login' })
} else {
// 加载动态菜单和路由
addDynamicMenuAndRoutes(userName, to, from)
next()
}
}
axios.js
// request 拦截器
instance.interceptors.request.use(
config => {
let token = Cookies.get('token')
// 1. 请求开始的时候可以结合 vuex 开启全屏 loading 动画
// console.log(store.state.loading)
// console.log('准备发送请求...')
// 2. 带上token
if (token) {
config.headers.token = token
} else {
// 重定向到登录页面
router.push('/login')
}
// 3. 根据请求方法,序列化传来的参数,根据后端需求是否序列化
if (config.method === 'post') {
// if (config.data.__proto__ === FormData.prototype
// || config.url.endsWith('path')
// || config.url.endsWith('mark')
// || config.url.endsWith('patchs')
// ) {
// } else {
// config.data = qs.stringify(config.data)
// }
}
return config
},
error => {
// 请求错误时
console.log('request:', error)
// 1. 判断请求超时
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
console.log('timeout请求超时')
// return service.request(originalRequest);// 再重复请求一次
}
// 2. 需要重定向到错误页面
const errorInfo = error.response
console.log(errorInfo)
if (errorInfo) {
console.log(1);
error = errorInfo.data // 页面那边catch的时候就能拿到详细的错误信息,看最下边的Promise.reject
const errorStatus = errorInfo.status; // 404 403 500 ...
router.push({
path: `/error/${errorStatus}`
})
}
return Promise.reject(error) // 在调用的那边可以拿到(catch)你想返回的错误信息
}
)