单点登录

main
xuechunyuan 3 years ago
parent b87edbbf94
commit 1069569f69
  1. 24
      src/api/user.js
  2. 2
      src/components/third-register/main.vue
  3. 2
      src/page/index/top/index.vue
  4. 2
      src/page/lock/index.vue
  5. 146
      src/page/login/index.vue
  6. 141
      src/page/login/newlogin.vue
  7. 8
      src/permission.js
  8. 7
      src/router/axios.js
  9. 12
      src/router/page/index.js
  10. 41
      src/store/modules/user.js
  11. 1
      vue.config.js

@ -37,16 +37,30 @@ export const loginBySocial = (tenantId, source, code, state) => request({
}
})
export const loginBySso = (state, code) => request({
// export const loginBySso = (state, code) => request({
// url: '/api/blade-auth/oauth/token',
// method: 'post',
// headers: {
// 'Tenant-Id': state
// },
// params: {
// tenantId: state,
// code,
// grant_type: "authorization_code",
// scope: "all",
// redirect_uri: website.redirectUri,
// }
// })
export const loginBySso = (SSOToken, grantType) => request({
url: '/api/blade-auth/oauth/token',
method: 'post',
headers: {
'Tenant-Id': state
'Tenant-Id': '000000'
},
params: {
tenantId: state,
code,
grant_type: "authorization_code",
tenantId: '000000',
SSOToken,
grant_type: grantType,
scope: "all",
redirect_uri: website.redirectUri,
}

@ -94,7 +94,7 @@
this.$alert("注册申请已提交,请耐心等待管理员通过!", '注册提示').then(() => {
this.$store.dispatch("LogOut").then(() => {
resetRouter();
this.$router.push({path: "/login"});
this.$router.push({path: "/newlogin"});
});
})
} else {

@ -68,7 +68,7 @@ export default {
}).then(() => {
this.$store.dispatch("LogOut").then(() => {
resetRouter();
this.$router.push({ path: "/login" });
this.$router.push({ path: "/newlogin" });
});
});
},

@ -49,7 +49,7 @@ export default {
type: "warning"
}).then(() => {
this.$store.dispatch("LogOut").then(() => {
this.$router.push({ path: "/login" });
this.$router.push({ path: "/newlogin" });
});
});
},

@ -1,57 +1,17 @@
<template>
<div class="login-container" ref="login" @keyup.enter.native="handleLogin">
<top-color v-show="false"></top-color>
<div class="login-weaper animated bounceInDown">
<!-- 左侧 -->
<div class="login-border">
<div class="login-main">
<div class="login-logo">
<img :src="require('@/assets/img/login/logo.png')" />
</div>
<div class="login-title">运维管理系统欢迎您</div>
<div class="login-subTitle">
WELCOME TO THE OPERATION AND MAINTENANCE<br />
MANAGEMENT SYSTEM
</div>
<userLogin></userLogin>
</div>
</div>
<!-- 右侧 -->
<div class="login-right">
<img :src="require('@/assets/img/login/login-right.png')" alt="">
</div>
</div>
<div class="login-container" v-loading="loading">
</div>
</template>
<script>
import userLogin from "./userlogin";
import codeLogin from "./codelogin";
import thirdLogin from "./thirdlogin";
import { mapGetters } from "vuex";
import { dateFormat } from "@/util/date";
import { validatenull } from "@/util/validate";
import topLang from "@/page/index/top/top-lang";
import topColor from "@/page/index/top/top-color";
import { getQueryString, getTopUrl } from "@/util/util";
import {getToken} from '@/util/auth'
export default {
name: "login",
components: {
userLogin,
codeLogin,
thirdLogin,
topLang,
topColor,
},
components: {},
data() {
return {
time: "",
socialForm: {
tenantId: "000000",
source: "",
code: "",
state: "",
},
loading: false
};
},
watch: {
@ -61,74 +21,52 @@ export default {
},
created() {
this.handleLogin();
this.getTime();
},
mounted() {},
mounted() {
},
computed: {
...mapGetters(["website", "tagWel"]),
},
props: [],
methods: {
getTime() {
setInterval(() => {
this.time = dateFormat(new Date());
}, 1000);
},
handleLogin() {
const topUrl = getTopUrl();
const redirectUrl = "/oauth/redirect/";
const ssoCode = "?code=";
this.socialForm.source = getQueryString("source");
this.socialForm.code = getQueryString("code");
this.socialForm.state = getQueryString("state");
if (
validatenull(this.socialForm.source) &&
topUrl.includes(redirectUrl)
) {
let source = topUrl.split("?")[0];
source = source.split(redirectUrl)[1];
this.socialForm.source = source;
}
if (
topUrl.includes(redirectUrl) &&
!validatenull(this.socialForm.source) &&
!validatenull(this.socialForm.code) &&
!validatenull(this.socialForm.state)
) {
const loading = this.$loading({
lock: true,
text: "第三方系统登录中,请稍后。。。",
spinner: "el-icon-loading",
});
this.$store
.dispatch("LoginBySocial", this.socialForm)
.then(() => {
window.location.href = topUrl.split(redirectUrl)[0];
this.$router.push({ path: this.tagWel.value });
loading.close();
})
.catch(() => {
loading.close();
});
} else if (
!topUrl.includes(redirectUrl) &&
!validatenull(this.socialForm.code) &&
!validatenull(this.socialForm.state)
) {
const loading = this.$loading({
lock: true,
text: "单点系统登录中,请稍后。。。",
spinner: "el-icon-loading",
});
const ssotoken = this.$route.query.SSOToken;
const token = getToken();
console.log('ssotken',ssotoken, '=======')
if (token) {
this.$router.push({ path: this.tagWel.value });
}else{
this.loading = true;
this.$store
.dispatch("LoginBySso", this.socialForm)
.then(() => {
window.location.href = topUrl.split(ssoCode)[0];
this.$router.push({ path: this.tagWel.value });
loading.close();
})
.catch(() => {
loading.close();
.dispatch("LoginBySso", {SSOToken: ssotoken,grantType:'yawei'})
.then((res) => {
this.loading = false;
console.log('=============登录成功')
this.$router.replace({ path: this.tagWel.value });
},err => {
this.loading = false;
console.log('err=======res',err)
if(err.error == 'invalid_request') {
window.location.href = err.error_description+'?strToken=' + encodeURI(window.location);//
}else if(err.error == 'invalid_grant') {
this.$confirm(err.error_description, '提示', {
confirmButtonText: '确定',
showClose: false,
showCancelButton: false,
type: 'warning'
}).then(() => {
this.$router.replace({ path: '/newlogin' });
})
}else {
this.$confirm(err.error_description, '提示', {
confirmButtonText: '确定',
showClose: false,
showCancelButton: false,
type: 'warning'
}).then(() => {
this.$router.replace({ path: '/newlogin' });
})
}
});
}
},

@ -0,0 +1,141 @@
<template>
<div class="login-container" ref="login" @keyup.enter.native="handleLogin">
<top-color v-show="false"></top-color>
<div class="login-weaper animated bounceInDown">
<!-- 左侧 -->
<div class="login-border">
<div class="login-main">
<div class="login-logo">
<img :src="require('@/assets/img/login/logo.png')" />
</div>
<div class="login-title">运维管理系统欢迎您</div>
<div class="login-subTitle">
WELCOME TO THE OPERATION AND MAINTENANCE<br />
MANAGEMENT SYSTEM
</div>
<userLogin></userLogin>
</div>
</div>
<!-- 右侧 -->
<div class="login-right">
<img :src="require('@/assets/img/login/login-right.png')" alt="">
</div>
</div>
</div>
</template>
<script>
import userLogin from "./userlogin";
import codeLogin from "./codelogin";
import thirdLogin from "./thirdlogin";
import { mapGetters } from "vuex";
import { dateFormat } from "@/util/date";
import { validatenull } from "@/util/validate";
import topLang from "@/page/index/top/top-lang";
import topColor from "@/page/index/top/top-color";
import { getQueryString, getTopUrl } from "@/util/util";
export default {
name: "newlogin",
components: {
userLogin,
codeLogin,
thirdLogin,
topLang,
topColor,
},
data() {
return {
time: "",
socialForm: {
tenantId: "000000",
source: "",
code: "",
state: "",
},
};
},
watch: {
$route() {
this.handleLogin();
},
},
created() {
this.handleLogin();
this.getTime();
},
mounted() {},
computed: {
...mapGetters(["website", "tagWel"]),
},
props: [],
methods: {
getTime() {
setInterval(() => {
this.time = dateFormat(new Date());
}, 1000);
},
handleLogin() {
const topUrl = getTopUrl();
const redirectUrl = "/oauth/redirect/";
const ssoCode = "?code=";
this.socialForm.source = getQueryString("source");
this.socialForm.code = getQueryString("code");
this.socialForm.state = getQueryString("state");
if (
validatenull(this.socialForm.source) &&
topUrl.includes(redirectUrl)
) {
let source = topUrl.split("?")[0];
source = source.split(redirectUrl)[1];
this.socialForm.source = source;
}
if (
topUrl.includes(redirectUrl) &&
!validatenull(this.socialForm.source) &&
!validatenull(this.socialForm.code) &&
!validatenull(this.socialForm.state)
) {
const loading = this.$loading({
lock: true,
text: "第三方系统登录中,请稍后。。。",
spinner: "el-icon-loading",
});
this.$store
.dispatch("LoginBySocial", this.socialForm)
.then(() => {
window.location.href = topUrl.split(redirectUrl)[0];
this.$router.push({ path: this.tagWel.value });
loading.close();
})
.catch(() => {
loading.close();
});
} else if (
!topUrl.includes(redirectUrl) &&
!validatenull(this.socialForm.code) &&
!validatenull(this.socialForm.state)
) {
const loading = this.$loading({
lock: true,
text: "单点系统登录中,请稍后。。。",
spinner: "el-icon-loading",
});
this.$store
.dispatch("LoginBySso", this.socialForm)
.then(() => {
window.location.href = topUrl.split(ssoCode)[0];
this.$router.push({ path: this.tagWel.value });
loading.close();
})
.catch(() => {
loading.close();
});
}
},
},
};
</script>
<style lang="scss" scoped>
@import "@/styles/login.scss";
</style>

@ -17,13 +17,13 @@ router.beforeEach((to, from, next) => {
if (getToken()) {
if (store.getters.isLock && to.path !== lockPage) { //如果系统激活锁屏,全部跳转到锁屏页
next({path: lockPage})
} else if (to.path === '/login') { //如果登录成功访问登录页跳转到主页
} else if (to.path === '/newlogin') { //如果登录成功访问登录页跳转到主页
next({path: '/'})
} else {
//如果用户信息为空则获取用户信息,获取用户信息失败,跳转到登录页
if (store.getters.token.length === 0) {
store.dispatch('FedLogOut').then(() => {
next({path: '/login'})
next({path: '/newlogin'})
})
} else {
const value = to.query.src || to.fullPath;
@ -57,7 +57,7 @@ router.beforeEach((to, from, next) => {
if (meta.isAuth === false) {
next()
} else {
next('/login')
next('/newlogin')
}
}
})
@ -68,7 +68,7 @@ router.afterEach(() => {
let i18n = store.getters.tag.meta.i18n;
title = router.$avueRouter.generateTitle(title, i18n);
//判断登录页的情况
if (router.history.current.fullPath === "/login") {
if (router.history.current.fullPath === "/newlogin") {
title = "登录";
}
//根据当前的标签也获取label的值动态设置浏览器标题

@ -59,21 +59,22 @@ axios.interceptors.request.use(config => {
axios.interceptors.response.use(res => {
//关闭 progress bar
// NProgress.done();
//获取状态码
const status = res.data.code || res.status;
const statusWhiteList = website.statusWhiteList || [];
const message = res.data.msg || res.data.error_description || '未知错误';
//如果在白名单里则自行catch逻辑处理
if (statusWhiteList.includes(status)) return Promise.reject(res);
//如果是401则跳转到登录页面
if (status === 401) store.dispatch('FedLogOut').then(() => router.push({path: '/login'}));
if (status === 401) store.dispatch('FedLogOut').then(() => router.push({path: '/newlogin'}));
// 如果请求为非200否者默认统一处理
if (status !== 200) {
if (status !== 200 && res.data.error == undefined) {
Message({
message: message,
type: 'error'
});
return Promise.reject(new Error(message))
} else if(res.data.error != undefined) {
return Promise.reject(res.data)
}
return res;
}, error => {

@ -1,7 +1,7 @@
import Layout from '@/page/index/'
export default [{
path: '/login',
path: '/login',//金宏网过渡页
name: '登录页',
component: () =>
import( /* webpackChunkName: "page" */ '@/page/login/index'),
@ -10,6 +10,16 @@ export default [{
isTab: false,
isAuth: false
}
},{
path: '/newlogin',
name: '登录页',
component: () =>
import( /* webpackChunkName: "page" */ '@/page/login/newlogin'),
meta: {
keepAlive: true,
isTab: false,
isAuth: false
}
},
{
path: '/lock',

@ -1,5 +1,5 @@
import {setToken, setRefreshToken, removeToken, removeRefreshToken} from '@/util/auth'
import {Message} from 'element-ui'
import {Message, MessageBox} from 'element-ui'
import {setStore, getStore} from '@/util/store'
import {isURL, validatenull} from '@/util/validate'
import {deepClone} from '@/util/util'
@ -105,23 +105,34 @@ const user = {
},
//根据单点信息登录
LoginBySso({commit}, userInfo) {
return new Promise((resolve) => {
loginBySso(userInfo.state, userInfo.code).then(res => {
const data = res.data;
if (data.error_description) {
Message({
message: data.error_description,
type: 'error'
})
} else {
commit('SET_TOKEN', data.access_token);
commit('SET_REFRESH_TOKEN', data.refresh_token);
commit('SET_USER_INFO', data);
commit('SET_TENANT_ID', data.tenant_id);
return new Promise((resolve, reject) => {
loginBySso(userInfo.SSOToken, userInfo.grantType).then(res => {
console.log('loginBySso=======res',res)
// const data = res.data;
if(res.error != 'invalid_request' && res.error != 'invalid_grant'){
commit('SET_TOKEN', res.data.access_token);
commit('SET_REFRESH_TOKEN', res.data.refresh_token);
commit('SET_USER_INFO', res.data);
commit('SET_TENANT_ID', res.data.tenant_id);
commit('DEL_ALL_TAG');
commit('CLEAR_LOCK');
}
resolve();
// if (data.error_description) {
// Message({
// message: data.error_description,
// type: 'error'
// })
// } else {
// commit('SET_TOKEN', data.access_token);
// commit('SET_REFRESH_TOKEN', data.refresh_token);
// commit('SET_USER_INFO', data);
// commit('SET_TENANT_ID', data.tenant_id);
// commit('DEL_ALL_TAG');
// commit('CLEAR_LOCK');
// }
resolve(res);
}).catch(err => {
reject(err);
})
})
},

@ -27,6 +27,7 @@ module.exports = {
'/api': {
//本地服务接口地址
target: 'http://192.168.3.36:81',
// target: 'http://192.168.1.12:81',
// target: 'http://192.168.1.102:81',
//远程演示服务地址,可用于直接启动项目
// target: 'http://10.133.191.105:81',

Loading…
Cancel
Save