fix: 接入cas单点登录
parent
ad9a90e252
commit
a4d103790d
|
@ -37,7 +37,7 @@ onMounted(() => {
|
||||||
}, 1000 * 2)
|
}, 1000 * 2)
|
||||||
})
|
})
|
||||||
const showMainApp = computed(() => {
|
const showMainApp = computed(() => {
|
||||||
return ['/login', '/sso', '/lockme', '/redirect', '/404', '/license'].includes(route.path)
|
return ['/login', '/caslogin', '/sso', '/lockme', '/redirect', '/404', '/license'].includes(route.path)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@media screen and(-ms-high-contrast:active),
|
@media screen and (-ms-high-contrast:active),
|
||||||
(-ms-high-contrast:none) {
|
(-ms-high-contrast:none) {
|
||||||
.el-table__header,
|
.el-table__header,
|
||||||
.el-table__body {
|
.el-table__body {
|
||||||
|
|
|
@ -1,169 +1,176 @@
|
||||||
<template>
|
<template>
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
<div class="user-content">
|
<div class="user-content">
|
||||||
<img :src="userData.portrait" class="head-portrait" />
|
<img :src="userData.portrait" class="head-portrait" />
|
||||||
<span class="user-name">{{ userData.name }}</span>
|
<span class="user-name">{{ userData.name }}</span>
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
</div>
|
</div>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu class="user-dropdown">
|
<a-menu class="user-dropdown">
|
||||||
<a-menu-item @click="openInfoDialog" class="menu-item"> <UserOutlined /> 个人信息 </a-menu-item>
|
<a-menu-item @click="openInfoDialog" class="menu-item"> <UserOutlined /> 个人信息 </a-menu-item>
|
||||||
<a-menu-item @click="openPwdDialog" class="menu-item"> <LockOutlined /> 修改密码 </a-menu-item>
|
<a-menu-item @click="openPwdDialog" class="menu-item"> <LockOutlined /> 修改密码 </a-menu-item>
|
||||||
<a-menu-item @click="logoutSystem()" class="menu-item"> <PoweroffOutlined /> 退出系统 </a-menu-item>
|
<a-menu-item @click="logoutSystem()" class="menu-item"> <PoweroffOutlined /> 退出系统 </a-menu-item>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
<a-modal title="修改密码" :maskClosable="false" width="600px" v-if="pwdDialogVisible" v-model:visible="pwdDialogVisible" @ok="modifyPwdSubmit" :confirmLoading="loading">
|
<a-modal title="修改密码" :maskClosable="false" width="600px" v-if="pwdDialogVisible" v-model:visible="pwdDialogVisible" @ok="modifyPwdSubmit" :confirmLoading="loading">
|
||||||
<a-form :model="pwdData" ref="pwdRef" :colon="true" :labelCol="{ span: 4 }">
|
<a-form :model="pwdData" ref="pwdRef" :colon="true" :labelCol="{ span: 4 }">
|
||||||
<a-form-item label="原密码" name="oldPassword" :rules="[required]">
|
<a-form-item label="原密码" name="oldPassword" :rules="[required]">
|
||||||
<a-input-password v-model:value="pwdData.oldPassword" auto-complete="off"></a-input-password>
|
<a-input-password v-model:value="pwdData.oldPassword" auto-complete="off"></a-input-password>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="新密码" name="newPassword" :rules="pwdRule">
|
<a-form-item label="新密码" name="newPassword" :rules="pwdRule">
|
||||||
<a-input-password v-model:value="pwdData.newPassword" auto-complete="off"></a-input-password>
|
<a-input-password v-model:value="pwdData.newPassword" auto-complete="off"></a-input-password>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="确认密码" name="confirmPassword" :rules="pwdRule">
|
<a-form-item label="确认密码" name="confirmPassword" :rules="pwdRule">
|
||||||
<a-input-password v-model:value="pwdData.confirmPassword" auto-complete="off"></a-input-password>
|
<a-input-password v-model:value="pwdData.confirmPassword" auto-complete="off"></a-input-password>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<InfoDialog ref="infoRef" :data="userData"></InfoDialog>
|
<InfoDialog ref="infoRef" :data="userData"></InfoDialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import crypto from 'utils/crypto.js'
|
import crypto from 'utils/crypto.js'
|
||||||
import { changePassword } from '@/services/manager'
|
import { changePassword } from '@/services/manager'
|
||||||
import { logout } from 'services'
|
import { logout } from 'services'
|
||||||
import InfoDialog from './InfoDialog.vue'
|
import { getCasConfig } from '@/store/utils'
|
||||||
import { computed, defineComponent, ref, createVNode } from 'vue'
|
import InfoDialog from './InfoDialog.vue'
|
||||||
import { message, Modal } from 'ant-design-vue'
|
import { computed, defineComponent, ref, createVNode } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { message, Modal } from 'ant-design-vue'
|
||||||
import { required, complexPassword } from '@/validate'
|
import { useStore } from 'vuex'
|
||||||
import { UserOutlined, PoweroffOutlined, LockOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons-vue'
|
import { required, complexPassword } from '@/validate'
|
||||||
|
import { UserOutlined, PoweroffOutlined, LockOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons-vue'
|
||||||
export default defineComponent({
|
|
||||||
components: { InfoDialog, UserOutlined, PoweroffOutlined, LockOutlined, DownOutlined },
|
export default defineComponent({
|
||||||
setup() {
|
components: { InfoDialog, UserOutlined, PoweroffOutlined, LockOutlined, DownOutlined },
|
||||||
const store = useStore()
|
setup() {
|
||||||
// 密码修改
|
const store = useStore()
|
||||||
const pwdData = ref({
|
// 密码修改
|
||||||
oldPassword: '',
|
const pwdData = ref({
|
||||||
newPassword: '',
|
oldPassword: '',
|
||||||
confirmPassword: ''
|
newPassword: '',
|
||||||
})
|
confirmPassword: ''
|
||||||
const pwdDialogVisible = ref(false)
|
})
|
||||||
function openPwdDialog() {
|
const pwdDialogVisible = ref(false)
|
||||||
pwdDialogVisible.value = true
|
function openPwdDialog() {
|
||||||
pwdData.value = {
|
pwdDialogVisible.value = true
|
||||||
oldPassword: '',
|
pwdData.value = {
|
||||||
newPassword: '',
|
oldPassword: '',
|
||||||
confirmPassword: ''
|
newPassword: '',
|
||||||
}
|
confirmPassword: ''
|
||||||
}
|
}
|
||||||
function checkPassword() {
|
}
|
||||||
const { newPassword, oldPassword, confirmPassword } = pwdData.value
|
function checkPassword() {
|
||||||
if (newPassword === oldPassword) {
|
const { newPassword, oldPassword, confirmPassword } = pwdData.value
|
||||||
message.error('新密码不能与原密码相同')
|
if (newPassword === oldPassword) {
|
||||||
return false
|
message.error('新密码不能与原密码相同')
|
||||||
}
|
return false
|
||||||
if (confirmPassword !== newPassword) {
|
}
|
||||||
message.error('确认密码与新密码不一致')
|
if (confirmPassword !== newPassword) {
|
||||||
return false
|
message.error('确认密码与新密码不一致')
|
||||||
}
|
return false
|
||||||
|
}
|
||||||
return true
|
|
||||||
}
|
return true
|
||||||
const pwdRef = ref()
|
}
|
||||||
const loading = ref(false)
|
const pwdRef = ref()
|
||||||
async function modifyPwdSubmit() {
|
const loading = ref(false)
|
||||||
try {
|
async function modifyPwdSubmit() {
|
||||||
const values = await pwdRef.value.validate()
|
try {
|
||||||
if (!checkPassword()) return
|
const values = await pwdRef.value.validate()
|
||||||
loading.value = true
|
if (!checkPassword()) return
|
||||||
const res = await changePassword(userData.value.id, {
|
loading.value = true
|
||||||
password: crypto.encrypt(values.newPassword),
|
const res = await changePassword(userData.value.id, {
|
||||||
oldPassword: crypto.encrypt(values.oldPassword)
|
password: crypto.encrypt(values.newPassword),
|
||||||
})
|
oldPassword: crypto.encrypt(values.oldPassword)
|
||||||
if (res.success) {
|
})
|
||||||
pwdDialogVisible.value = false
|
if (res.success) {
|
||||||
message.success(res.message)
|
pwdDialogVisible.value = false
|
||||||
store.dispatch('permission/ResetRoutes')
|
message.success(res.message)
|
||||||
}
|
store.dispatch('permission/ResetRoutes')
|
||||||
} catch (error) {
|
}
|
||||||
console.log(error)
|
} catch (error) {
|
||||||
}
|
console.log(error)
|
||||||
loading.value = false
|
}
|
||||||
}
|
loading.value = false
|
||||||
const userData = computed(() => store.getters.userData || {})
|
}
|
||||||
const pwdRule = computed(() => {
|
const userData = computed(() => store.getters.userData || {})
|
||||||
const rule = store.state.app.systemConfig.pwdStrength
|
const pwdRule = computed(() => {
|
||||||
if (rule === 'required') return [required]
|
const rule = store.state.app.systemConfig.pwdStrength
|
||||||
return [required, complexPassword]
|
if (rule === 'required') return [required]
|
||||||
})
|
return [required, complexPassword]
|
||||||
// 登出
|
})
|
||||||
function logoutSystem() {
|
// 登出
|
||||||
Modal.confirm({
|
function logoutSystem() {
|
||||||
title: '提示',
|
Modal.confirm({
|
||||||
icon: createVNode(ExclamationCircleOutlined),
|
title: '提示',
|
||||||
content: '您确定要退出该系统吗?',
|
icon: createVNode(ExclamationCircleOutlined),
|
||||||
async onOk() {
|
content: '您确定要退出该系统吗?',
|
||||||
const res = await logout()
|
async onOk() {
|
||||||
if (res.success) {
|
const { isCASLogin, casLogoutPath } = await getCasConfig()
|
||||||
store.dispatch('permission/ResetRoutes')
|
if (isCASLogin) {
|
||||||
}
|
location.href = casLogoutPath
|
||||||
}
|
} else {
|
||||||
})
|
const res = await logout()
|
||||||
}
|
if (res.success) {
|
||||||
// 个人信息
|
await store.dispatch('permission/ResetRoutes', false)
|
||||||
const infoRef = ref()
|
location.href = '/login'
|
||||||
function openInfoDialog() {
|
}
|
||||||
infoRef.value.open()
|
}
|
||||||
}
|
}
|
||||||
return {
|
})
|
||||||
loading,
|
}
|
||||||
pwdData,
|
// 个人信息
|
||||||
pwdDialogVisible,
|
const infoRef = ref()
|
||||||
pwdRef,
|
function openInfoDialog() {
|
||||||
pwdRule,
|
infoRef.value.open()
|
||||||
openPwdDialog,
|
}
|
||||||
modifyPwdSubmit,
|
return {
|
||||||
logoutSystem,
|
loading,
|
||||||
infoRef,
|
pwdData,
|
||||||
openInfoDialog,
|
pwdDialogVisible,
|
||||||
userData,
|
pwdRef,
|
||||||
required
|
pwdRule,
|
||||||
}
|
openPwdDialog,
|
||||||
}
|
modifyPwdSubmit,
|
||||||
})
|
logoutSystem,
|
||||||
</script>
|
infoRef,
|
||||||
<style lang="scss" scoped>
|
openInfoDialog,
|
||||||
.user-content {
|
userData,
|
||||||
margin-right: 10px;
|
required
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
}
|
||||||
cursor: pointer;
|
})
|
||||||
.head-portrait {
|
</script>
|
||||||
display: inline-block;
|
<style lang="scss" scoped>
|
||||||
width: 24px;
|
.user-content {
|
||||||
height: 24px;
|
margin-right: 10px;
|
||||||
border-radius: 50%;
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
}
|
cursor: pointer;
|
||||||
.user-name {
|
.head-portrait {
|
||||||
max-width: 140px;
|
display: inline-block;
|
||||||
white-space: nowrap;
|
width: 24px;
|
||||||
overflow: hidden;
|
height: 24px;
|
||||||
text-overflow: ellipsis;
|
border-radius: 50%;
|
||||||
font-size: 14px;
|
}
|
||||||
margin: 0 2px 0 5px;
|
}
|
||||||
}
|
.user-name {
|
||||||
.user-dropdown {
|
max-width: 140px;
|
||||||
background: #2c2e3b;
|
white-space: nowrap;
|
||||||
border-color: #2c2e3b;
|
overflow: hidden;
|
||||||
::v-deep(.ant-dropdown-menu-item) {
|
text-overflow: ellipsis;
|
||||||
color: #ccc;
|
font-size: 14px;
|
||||||
&:hover {
|
margin: 0 2px 0 5px;
|
||||||
background: #2d8cf0 !important;
|
}
|
||||||
color: #fff;
|
.user-dropdown {
|
||||||
}
|
background: #2c2e3b;
|
||||||
}
|
border-color: #2c2e3b;
|
||||||
}
|
::v-deep(.ant-dropdown-menu-item) {
|
||||||
</style>
|
color: #ccc;
|
||||||
|
&:hover {
|
||||||
|
background: #2d8cf0 !important;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,52 +1,81 @@
|
||||||
/**
|
/**
|
||||||
* Created by HaijunZhang on 2018/11/12.
|
* Created by HaijunZhang on 2018/11/12.
|
||||||
*/
|
*/
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import { getToken, setToken } from 'utils/auth'
|
import { getToken, setToken } from 'utils/auth'
|
||||||
import { getQuery } from 'utils'
|
import { getQuery } from 'utils'
|
||||||
import { isEmpty, assign } from 'lodash-es'
|
import { isEmpty, assign } from 'lodash-es'
|
||||||
|
import { getCasConfig, goLogin } from './store/utils'
|
||||||
const { token } = getQuery(location.hash)
|
|
||||||
if (token) {
|
const redirectToCasLogin = (to, next, ticket, casLoginPath) => {
|
||||||
setToken(token)
|
if (!ticket) {
|
||||||
}
|
location.href = casLoginPath
|
||||||
|
return
|
||||||
const whiteList = ['/login', '/404', '/401', '/license', '/sso']
|
}
|
||||||
router.beforeEach(async (to, from, next) => {
|
if (to.path === '/caslogin') {
|
||||||
if (isEmpty(history.state.current)) {
|
next()
|
||||||
assign(history.state, { current: from.fullPath })
|
return
|
||||||
}
|
}
|
||||||
if (getToken()) {
|
next(`/caslogin?ticket=${ticket}`)
|
||||||
// 判断用户是否处于登录状态
|
}
|
||||||
if (to.path === '/login') {
|
|
||||||
// 如果已经登录重定向到主页
|
const { token } = getQuery(location.hash)
|
||||||
await store.dispatch('permission/ResetRoutes', false)
|
if (token) {
|
||||||
next('/login')
|
setToken(token)
|
||||||
} else {
|
}
|
||||||
// 为null的场景: 刷新页面或者新开窗口;
|
|
||||||
const addRoutes = store.getters.addRoutes
|
const whiteList = ['/login', '/caslogin', '/404', '/401', '/license', '/sso']
|
||||||
if (addRoutes) {
|
router.beforeEach(async (to, from, next) => {
|
||||||
next()
|
const ticket = to.query.ticket || new URLSearchParams(location.search).get('ticket')
|
||||||
} else {
|
if (isEmpty(history.state.current)) {
|
||||||
try {
|
assign(history.state, { current: from.fullPath })
|
||||||
await store.dispatch('permission/GenerateRoutes')
|
}
|
||||||
store.dispatch('GetUserInfo')
|
if (getToken()) {
|
||||||
next({ ...to, replace: true })
|
// 判断用户是否处于登录状态
|
||||||
} catch (error) {
|
if (to.path === '/login' || to.path === '/caslogin') {
|
||||||
// remove token and go to login page to re-login
|
// 如果已经登录重定向到主页
|
||||||
await store.dispatch('permission/ResetRoutes', false)
|
await store.dispatch('permission/ResetRoutes', false)
|
||||||
next('/login')
|
const { isCASLogin, casLoginPath } = await getCasConfig()
|
||||||
}
|
if (!isCASLogin) {
|
||||||
}
|
next('/login')
|
||||||
}
|
} else {
|
||||||
} else {
|
redirectToCasLogin(to, next, ticket, casLoginPath)
|
||||||
// 用户没有登录
|
}
|
||||||
if (whiteList.includes(to.path)) {
|
} else {
|
||||||
// 在白名单里直接跳转
|
// 为null的场景: 刷新页面或者新开窗口;
|
||||||
next()
|
const addRoutes = store.getters.addRoutes
|
||||||
} else {
|
if (addRoutes) {
|
||||||
next('/login')
|
next()
|
||||||
}
|
} else {
|
||||||
}
|
try {
|
||||||
})
|
await store.dispatch('permission/GenerateRoutes')
|
||||||
|
store.dispatch('GetUserInfo')
|
||||||
|
next({ ...to, replace: true })
|
||||||
|
} catch (error) {
|
||||||
|
// remove token and go to login page to re-login
|
||||||
|
await store.dispatch('permission/ResetRoutes', false)
|
||||||
|
const { isCASLogin, casLoginPath } = await getCasConfig()
|
||||||
|
if (!isCASLogin) {
|
||||||
|
next('/login')
|
||||||
|
} else {
|
||||||
|
redirectToCasLogin(to, next, ticket, casLoginPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 用户没有登录
|
||||||
|
if (whiteList.includes(to.path)) {
|
||||||
|
// 在白名单里直接跳转
|
||||||
|
const { isCASLogin, casLoginPath } = await getCasConfig()
|
||||||
|
if (!isCASLogin) {
|
||||||
|
next()
|
||||||
|
} else {
|
||||||
|
redirectToCasLogin(to, next, ticket, casLoginPath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goLogin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
|
@ -5,7 +5,12 @@ const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
path: '/login',
|
path: '/login',
|
||||||
component: () => import('views/login/login.vue')
|
component: () => import('views/login/userLogin.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CASLogin',
|
||||||
|
path: '/caslogin',
|
||||||
|
component: () => import('views/login/casLogin.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sso',
|
path: '/sso',
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
import request from 'utils/request'
|
import request from 'utils/request'
|
||||||
import { wrapperParams } from 'utils'
|
import { wrapperParams } from 'utils'
|
||||||
|
|
||||||
|
export function loginByCas(params) {
|
||||||
|
return request.post('/sms/v1/users/login/cas', wrapperParams(params))
|
||||||
|
}
|
||||||
|
|
||||||
export function login(params) {
|
export function login(params) {
|
||||||
return request.post('/sms/v1/users/login', params)
|
return request.post('/sms/v1/users/login', params)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { getUserPermissions } from 'services'
|
||||||
import BlankView from '@/layouts/blank.vue'
|
import BlankView from '@/layouts/blank.vue'
|
||||||
import router, { resetRouter } from '@/router'
|
import router, { resetRouter } from '@/router'
|
||||||
import { menuKey, enablePermissionStorage } from '@/config'
|
import { menuKey, enablePermissionStorage } from '@/config'
|
||||||
import { urlToList } from '../utils'
|
import { urlToList, goLogin } from '../utils'
|
||||||
import actionStore from '@/core/actions'
|
import actionStore from '@/core/actions'
|
||||||
|
|
||||||
const resultRoutes = []
|
const resultRoutes = []
|
||||||
|
@ -167,7 +167,7 @@ const actions = {
|
||||||
// 重置标签信息
|
// 重置标签信息
|
||||||
dispatch('tagsView/delAllViews', null, { root: true })
|
dispatch('tagsView/delAllViews', null, { root: true })
|
||||||
removeToken()
|
removeToken()
|
||||||
if (redirectToLogin) window.location.href = '/login'
|
if (redirectToLogin) goLogin()
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,45 @@
|
||||||
export const setBrowser = (icon, title) => {
|
import { getSystemConfigs } from 'services'
|
||||||
const head = document.getElementsByTagName('head')[0]
|
import store from '@/store'
|
||||||
const linkTag = document.createElement('link')
|
export const setBrowser = (icon, title) => {
|
||||||
linkTag.href = icon
|
const head = document.getElementsByTagName('head')[0]
|
||||||
linkTag.setAttribute('rel', 'shortcut icon')
|
const linkTag = document.createElement('link')
|
||||||
linkTag.setAttribute('type', 'image/x-icon')
|
linkTag.href = icon
|
||||||
head.appendChild(linkTag)
|
linkTag.setAttribute('rel', 'shortcut icon')
|
||||||
document.title = title
|
linkTag.setAttribute('type', 'image/x-icon')
|
||||||
}
|
head.appendChild(linkTag)
|
||||||
// /system/configs/page -> [ '/system','/system/configs','/system/configs/page']
|
document.title = title
|
||||||
export const urlToList = (url) => {
|
}
|
||||||
const urllist = url.split('/').filter((i) => i)
|
// /system/configs/page -> [ '/system','/system/configs','/system/configs/page']
|
||||||
return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`)
|
export const urlToList = (url) => {
|
||||||
}
|
const urllist = url.split('/').filter((i) => i)
|
||||||
|
return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`)
|
||||||
|
}
|
||||||
|
export const getPageConfigs = async () => {
|
||||||
|
const res = await getSystemConfigs({ category: '界面配置' })
|
||||||
|
if (res.success) {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
throw res.data
|
||||||
|
}
|
||||||
|
export const getCasConfig = async () => {
|
||||||
|
const Store = store
|
||||||
|
let pageConfig = Store?.getters?.pageConfig || {}
|
||||||
|
if (!Object.keys(pageConfig).length) {
|
||||||
|
pageConfig = (await getPageConfigs()) || {}
|
||||||
|
}
|
||||||
|
const { cas, casLoginUrl, casLoginoutUrl } = pageConfig
|
||||||
|
const isCASLogin = (cas === 'true' || cas === true) && !!casLoginUrl
|
||||||
|
const casLoginPath = `${casLoginUrl}?service=${location.origin}/caslogin`
|
||||||
|
const casLogoutPath = `${casLoginoutUrl}?service=${location.origin}/caslogin`
|
||||||
|
return { isCASLogin, cas, casLoginPath, casLogoutPath }
|
||||||
|
}
|
||||||
|
export const goLogin = async (forceCasRedirect = false) => {
|
||||||
|
const { isCASLogin, casLoginPath } = await getCasConfig()
|
||||||
|
let path = '/login'
|
||||||
|
// forceCasRedirect avoids reusing stale CAS tickets during logout or failed auth attempts
|
||||||
|
const ticket = forceCasRedirect ? null : new URLSearchParams(location.search).get('ticket')
|
||||||
|
if (isCASLogin) {
|
||||||
|
path = ticket ? `/caslogin?ticket=${ticket}` : casLoginPath
|
||||||
|
}
|
||||||
|
window.location.href = path
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ import 'nprogress/nprogress.css'
|
||||||
import { notification } from 'ant-design-vue'
|
import { notification } from 'ant-design-vue'
|
||||||
import { getToken } from 'utils/auth'
|
import { getToken } from 'utils/auth'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
|
import { getCasConfig, goLogin } from '@/store/utils'
|
||||||
|
import { logout } from '@/services'
|
||||||
|
|
||||||
const codeMessage = {
|
const codeMessage = {
|
||||||
200: '服务器成功返回请求的数据。',
|
200: '服务器成功返回请求的数据。',
|
||||||
|
@ -92,9 +94,17 @@ axiosInstance.interceptors.response.use(
|
||||||
break
|
break
|
||||||
case '401':
|
case '401':
|
||||||
case '509':
|
case '509':
|
||||||
store.dispatch('permission/ResetRoutes')
|
store.dispatch('permission/ResetRoutes', false).then(() => {
|
||||||
break
|
getCasConfig().then(({ isCASLogin, casLogoutPath }) => {
|
||||||
default:
|
if (isCASLogin) {
|
||||||
|
location.href = casLogoutPath
|
||||||
|
} else {
|
||||||
|
logout().then((res) => {
|
||||||
|
if (res.success) goLogin()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if (!options.ignoreError) {
|
if (!options.ignoreError) {
|
||||||
notification.error({
|
notification.error({
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<template>
|
||||||
|
<div class="casLogin">{{ msg }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { loginByCas } from 'services'
|
||||||
|
import setLoginData from './tools'
|
||||||
|
import { removeToken } from 'utils/auth'
|
||||||
|
import { goLogin } from '@/store/utils'
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
msg: '',
|
||||||
|
url: window.location.href
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
let ticket = this.getUrlKey('ticket')
|
||||||
|
if (!ticket || ticket == '') {
|
||||||
|
const { redirect } = this.$route.query
|
||||||
|
const path = redirect ? redirect.split('/#')[1] : '/sms-web/resource_dashboard'
|
||||||
|
this.$router.replace({ path })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const service = `${window.location.origin}/caslogin`
|
||||||
|
this.login(ticket, service)
|
||||||
|
},
|
||||||
|
getUrlKey(name) {
|
||||||
|
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(this.url) || ['', ''])[1].replace(/\+/g, '%20')) || null
|
||||||
|
},
|
||||||
|
handleLoginAfter(data) {
|
||||||
|
setLoginData(data)
|
||||||
|
const { redirect } = this.$route.query
|
||||||
|
const path = redirect ? redirect.split('/#')[1] : '/sms-web/resource_dashboard'
|
||||||
|
this.$router.replace(path)
|
||||||
|
localStorage.removeItem('lockData')
|
||||||
|
},
|
||||||
|
login(ticket, service) {
|
||||||
|
loginByCas({ ticket, service })
|
||||||
|
.then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
this.handleLoginAfter(res.data)
|
||||||
|
this.msg = res.message
|
||||||
|
} else {
|
||||||
|
console.log(res.message, 'res.message')
|
||||||
|
goLogin(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.msg = '登录失败'
|
||||||
|
removeToken()
|
||||||
|
goLogin(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -59,10 +59,10 @@ export default {
|
||||||
remember: false,
|
remember: false,
|
||||||
loginForm: {
|
loginForm: {
|
||||||
account: '',
|
account: '',
|
||||||
password: '',
|
password: ''
|
||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
capsTooltip: false,
|
capsTooltip: false
|
||||||
})
|
})
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const configs = computed(() => store.getters.pageConfig)
|
const configs = computed(() => store.getters.pageConfig)
|
||||||
|
@ -84,7 +84,7 @@ export default {
|
||||||
if (state.remember) {
|
if (state.remember) {
|
||||||
const obj = {
|
const obj = {
|
||||||
account: state.loginForm.account,
|
account: state.loginForm.account,
|
||||||
password: encrypt(state.loginForm.password),
|
password: encrypt(state.loginForm.password)
|
||||||
}
|
}
|
||||||
localStorage.setItem('cmcLoginData', JSON.stringify(obj))
|
localStorage.setItem('cmcLoginData', JSON.stringify(obj))
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,12 +104,14 @@ export default {
|
||||||
const res = await login({
|
const res = await login({
|
||||||
account,
|
account,
|
||||||
password: encrypt(password),
|
password: encrypt(password),
|
||||||
isManager: true,
|
isManager: true
|
||||||
})
|
})
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
goLogin(res.data)
|
goLogin(res.data)
|
||||||
}
|
}
|
||||||
} catch (error) {}
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
state.loading = false
|
state.loading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,9 +133,9 @@ export default {
|
||||||
configs,
|
configs,
|
||||||
loginFormRef,
|
loginFormRef,
|
||||||
handleLogin,
|
handleLogin,
|
||||||
checkCapslock,
|
checkCapslock
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue