两个系统之间免登陆跳转

685 阅读3分钟

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的话 路由是要重新定位到登录页面的

image.png

所以在这里我们发完请求 拿到后端返回的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) 这时候就可以完整的显示了

image.png

完整代码:

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)你想返回的错误信息
      }
    )