需求:判断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('未选择菜单,请跟管理员联系!')
}
}
}
})
}
}
}