vue中sso单点登录实现方式用code换token

需求:判断url中是否有code,如果有code则调用登录接口用code当作用户名获取token,如果没有code说明已经登录,若调用其他接口(除登录以外)没有token则返回401

什么是单点登录?简单地说就是在多系统应用中,用户只需在一个地方登录,就可以访问所有的系统应用;

比如某宝,就属于多系统平台,既有买家购物系统、交易支付系统,还有卖家店铺管理系统、流量统计系统等等,如果没有单点登录,很简单的跨系统场景:假如有一个用户既是买家又是卖家,用户从卖家系统登录后,如果想要去购物,就要再次登录买家购物系统,支付的时候再登录一次交易支付系统,用户是不是该emo了?如果有了单点登录,用户只需在其中某个系统登录一次,其他系统也自动登录,退出也是一次退出则全退出;

比如,某猫和某宝我们很明显知道这是两个系统,但你在某猫登录以后,某宝也会自动登录,这就是单点登录的一种;

可以看作是有一个授权中心,这个授权中心服务于所有的系统,用户登录/退出都经过授权中心;

简单逻辑示例图

第一种方法:在main.js种判断url是否存在code 

main.js

import Vue from 'vue'
import { start } from '@/utils/sso.js'
import App from './App'
import store from './store'
import router from './router'

function setup(){
    new Vue({
        el: '#app',
        router,
        store,
        render: h => h(App)
    })
}

start(()=>{
    setup()
})

 sso.js

import axios from 'axios'
import user from '@/api/user'

export function start(next){
    let code = getQueryVariable('code')
    if(code){
        getTokenByCode(code, next)
    }else{
        user.getUserInfo().then((res)=>{
            typeof next==='function'?next():''
        })
    }
}

function getQueryVariable(variable) {
    let query = window.location.search.substring(1)
    let vars = query.split('&')
    for (let i = 0; i < vars.length; i++) {
        let pair = vars[i].split('=')
        if (pair[0] === variable) {
            return pair[1]
        }
    }
    return ''
}
function getTokenByCode(code, next){
    axios({
        url: 'get/token',
        data: { code },
        method: 'post'
    }).then((res)=>{
        localStorage.setItem('access_token', res.access_token)
        typeof next==='function'?next():''
    })
}

第二种方法是在container.vue使用route来实现

 async beforeRouteEnter(to, from, next) {
    const url = window.location.href
    const urlSplit1 = url.split('?')
    const urlSplit2 = urlSplit1[1] ? urlSplit1[1].split('&') : []
    const tokenUrl = urlSplit2.find((ele) => {
      if (ele.includes('code=')) {
        return ele
      }
    })
    if (!tokenUrl) {
       console.log('code不存在')
      next()
    } else {
      const token = tokenUrl.split('=')[1]
      const formData = new FormData()
      formData.append('userName', token)
      formData.append('password', getUuid())
      formData.append('sso', 1)
      const resData = await Login(formData).then((res) => {
        if (res.code === 0) {
          return res.data
        } else {
          return '登录失败'
        }
      })
      if (resData !== '登录失败') {
        next((vm) => {
          if (resData) {
            const params = urlSplit1[1] ? urlSplit1[1].split('/') : []
            if (params.length) {
              window.location.href = urlSplit1[0] + '#/' 
              } else {
                return vm.$message.warning('未选择菜单,请跟管理员联系!')
              }
            }
          }
        })
      }
    }
  }

猜你喜欢

转载自blog.csdn.net/Lucky_girl_wan/article/details/127570990