修改密码加密
This commit is contained in:
parent
41b9474300
commit
3378ab4a49
|
@ -70,7 +70,7 @@ const compareTag = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 免登录白名单 */
|
/** 免登录白名单 */
|
||||||
const whiteList = ['/login', '/social/callback', '/pwdExpired']
|
const whiteList = ['/login', '/pwdExpired']
|
||||||
|
|
||||||
/** 是否已经生成过路由表 */
|
/** 是否已经生成过路由表 */
|
||||||
let hasRouteFlag = false
|
let hasRouteFlag = false
|
||||||
|
@ -93,7 +93,7 @@ export const setupRouterGuard = (router: Router) => {
|
||||||
if (!hasRouteFlag) {
|
if (!hasRouteFlag) {
|
||||||
try {
|
try {
|
||||||
await userStore.getInfo()
|
await userStore.getInfo()
|
||||||
if (userStore.userInfo.pwdExpired && to.path !== '/pwdExpired') {
|
if (!userStore.pwdExpiredShow && to.path !== '/pwdExpired') {
|
||||||
Message.warning('密码已过期,请修改密码')
|
Message.warning('密码已过期,请修改密码')
|
||||||
next('/pwdExpired')
|
next('/pwdExpired')
|
||||||
}
|
}
|
||||||
|
|
|
@ -389,11 +389,7 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/social/callback',
|
|
||||||
component: () => import('@/views/login/social/index.vue'),
|
|
||||||
meta: { hidden: true },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/pwdExpired',
|
path: '/pwdExpired',
|
||||||
component: () => import('@/views/login/pwdExpired/index.vue'),
|
component: () => import('@/views/login/pwdExpired/index.vue'),
|
||||||
|
|
|
@ -4,18 +4,18 @@ import { resetRouter } from '@/router'
|
||||||
import {
|
import {
|
||||||
type AccountLoginReq,
|
type AccountLoginReq,
|
||||||
AuthTypeConstants,
|
AuthTypeConstants,
|
||||||
type EmailLoginReq,
|
|
||||||
type PhoneLoginReq,
|
type PhoneLoginReq,
|
||||||
type UserDetail,
|
type UserDetail,
|
||||||
type DeptDetail,
|
type DeptDetail,
|
||||||
type RoleDetail,
|
type RoleDetail,
|
||||||
type UserInfo,
|
type UserInfo,
|
||||||
accountLogin as accountLoginApi,
|
accountLogin as accountLoginApi,
|
||||||
emailLogin as emailLoginApi,
|
|
||||||
getUserInfo as getUserInfoApi,
|
getUserInfo as getUserInfoApi,
|
||||||
logout as logoutApi,
|
logout as logoutApi,
|
||||||
phoneLogin as phoneLoginApi,
|
phoneLogin as phoneLoginApi,
|
||||||
socialLogin as socialLoginApi,
|
|
||||||
} from '@/apis'
|
} from '@/apis'
|
||||||
import { clearToken, getToken, setToken } from '@/utils/auth'
|
import { clearToken, getToken, setToken } from '@/utils/auth'
|
||||||
import { resetHasRouteFlag } from '@/router/guard'
|
import { resetHasRouteFlag } from '@/router/guard'
|
||||||
|
@ -64,17 +64,12 @@ const storeSetup = () => {
|
||||||
// 登录
|
// 登录
|
||||||
const accountLogin = async (req: AccountLoginReq) => {
|
const accountLogin = async (req: AccountLoginReq) => {
|
||||||
const res = await accountLoginApi({ ...req })
|
const res = await accountLoginApi({ ...req })
|
||||||
setToken(res.data.tokenValue)
|
|
||||||
token.value = res.data.tokenValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 邮箱登录
|
|
||||||
const emailLogin = async (req: EmailLoginReq) => {
|
|
||||||
const res = await emailLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.EMAIL })
|
|
||||||
setToken(res.data.token)
|
setToken(res.data.token)
|
||||||
token.value = res.data.token
|
token.value = res.data.token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 手机号登录
|
// 手机号登录
|
||||||
const phoneLogin = async (req: PhoneLoginReq) => {
|
const phoneLogin = async (req: PhoneLoginReq) => {
|
||||||
const res = await phoneLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.PHONE })
|
const res = await phoneLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.PHONE })
|
||||||
|
@ -82,12 +77,7 @@ const storeSetup = () => {
|
||||||
token.value = res.data.token
|
token.value = res.data.token
|
||||||
}
|
}
|
||||||
|
|
||||||
// 三方账号登录
|
|
||||||
const socialLogin = async (source: string, req: any) => {
|
|
||||||
const res = await socialLoginApi({ ...req, source, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.SOCIAL })
|
|
||||||
setToken(res.data.token)
|
|
||||||
token.value = res.data.token
|
|
||||||
}
|
|
||||||
|
|
||||||
// 退出登录回调
|
// 退出登录回调
|
||||||
const logoutCallBack = async () => {
|
const logoutCallBack = async () => {
|
||||||
|
@ -172,9 +162,7 @@ const storeSetup = () => {
|
||||||
permissions,
|
permissions,
|
||||||
pwdExpiredShow,
|
pwdExpiredShow,
|
||||||
accountLogin,
|
accountLogin,
|
||||||
emailLogin,
|
|
||||||
phoneLogin,
|
phoneLogin,
|
||||||
socialLogin,
|
|
||||||
logout,
|
logout,
|
||||||
logoutCallBack,
|
logoutCallBack,
|
||||||
getInfo,
|
getInfo,
|
||||||
|
|
|
@ -26,9 +26,17 @@ export function encryptByRsa(txt: string) {
|
||||||
return encryptor.encrypt(txt) // 对数据进行加密
|
return encryptor.encrypt(txt) // 对数据进行加密
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultKeyWork = 'XwKsGlMcdPMEhR1B'
|
/**
|
||||||
|
* AES加密
|
||||||
export function encryptByAes(word, keyWord = defaultKeyWork) {
|
* @param word 要加密的密码
|
||||||
|
* @param account 账号,用于生成加密密钥
|
||||||
|
* @returns 加密后的字符串
|
||||||
|
*/
|
||||||
|
export function encryptByAes(word: string, account: string) {
|
||||||
|
// 对账号做md5计算,然后取8-24位作为密钥(16个字符)
|
||||||
|
const accountMd5 = md5(account).toString()
|
||||||
|
const keyWord = accountMd5.substring(8, 24) // 取8-24位(索引8-23,共16位)
|
||||||
|
|
||||||
const key = CryptoJS.enc.Utf8.parse(keyWord)
|
const key = CryptoJS.enc.Utf8.parse(keyWord)
|
||||||
const arcs = CryptoJS.enc.Utf8.parse(word)
|
const arcs = CryptoJS.enc.Utf8.parse(word)
|
||||||
const encrypted = CryptoJS.AES.encrypt(arcs, key, {
|
const encrypted = CryptoJS.AES.encrypt(arcs, key, {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import { type FormInstance, Message } from '@arco-design/web-vue'
|
||||||
import { useStorage } from '@vueuse/core'
|
import { useStorage } from '@vueuse/core'
|
||||||
import { getImageCaptcha } from '@/apis/common'
|
import { getImageCaptcha } from '@/apis/common'
|
||||||
import { useTabsStore, useUserStore } from '@/stores'
|
import { useTabsStore, useUserStore } from '@/stores'
|
||||||
import { encryptByRsa } from '@/utils/encrypt'
|
import { encryptByAes } from '@/utils/encrypt'
|
||||||
|
|
||||||
const loginConfig = useStorage('login-config', {
|
const loginConfig = useStorage('login-config', {
|
||||||
rememberMe: true,
|
rememberMe: true,
|
||||||
|
@ -101,7 +101,7 @@ const handleLogin = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
await userStore.accountLogin({
|
await userStore.accountLogin({
|
||||||
account: form.account,
|
account: form.account,
|
||||||
password: 'Csq+AVwlEzX3r5vfxL7d/g==',
|
password: encryptByAes(form.password, form.account),
|
||||||
})
|
})
|
||||||
tabsStore.reset()
|
tabsStore.reset()
|
||||||
const { redirect, ...othersQuery } = router.currentRoute.value.query
|
const { redirect, ...othersQuery } = router.currentRoute.value.query
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="12" :md="11">
|
<a-col :xs="24" :sm="12" :md="11">
|
||||||
<div class="login-right">
|
<div class="login-right">
|
||||||
<h3 v-if="isEmailLogin" class="login-right__title">邮箱登录</h3>
|
<a-tabs v-model:activeKey="activeTab" class="login-right__form">
|
||||||
<EmailLogin v-if="isEmailLogin" />
|
|
||||||
<a-tabs v-else v-model:activeKey="activeTab" class="login-right__form">
|
|
||||||
<a-tab-pane key="1" title="账号登录">
|
<a-tab-pane key="1" title="账号登录">
|
||||||
<component :is="AccountLogin" v-if="activeTab === '1'" />
|
<component :is="AccountLogin" v-if="activeTab === '1'" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
@ -24,19 +22,6 @@
|
||||||
<component :is="PhoneLogin" v-if="activeTab === '2'" />
|
<component :is="PhoneLogin" v-if="activeTab === '2'" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<div class="login-right__oauth">
|
|
||||||
<a-divider orientation="center">其他登录方式</a-divider>
|
|
||||||
<div class="list">
|
|
||||||
<div v-if="isEmailLogin" class="mode item" @click="toggleLoginMode"><icon-user /> 账号/手机号登录</div>
|
|
||||||
<div v-else class="mode item" @click="toggleLoginMode"><icon-email /> 邮箱登录</div>
|
|
||||||
<a class="item" title="使用 Gitee 账号登录" @click="onOauth('gitee')">
|
|
||||||
<GiSvgIcon name="gitee" :size="24" />
|
|
||||||
</a>
|
|
||||||
<a class="item" title="使用 GitHub 账号登录" @click="onOauth('github')">
|
|
||||||
<GiSvgIcon name="github" :size="24" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
@ -60,9 +45,7 @@
|
||||||
<a-row align="stretch" class="login-box">
|
<a-row align="stretch" class="login-box">
|
||||||
<a-col :xs="24" :sm="12" :md="11">
|
<a-col :xs="24" :sm="12" :md="11">
|
||||||
<div class="login-right">
|
<div class="login-right">
|
||||||
<h3 v-if="isEmailLogin" class="login-right__title">邮箱登录</h3>
|
<a-tabs v-model:activeKey="activeTab" class="login-right__form">
|
||||||
<EmailLogin v-if="isEmailLogin" />
|
|
||||||
<a-tabs v-else v-model:activeKey="activeTab" class="login-right__form">
|
|
||||||
<a-tab-pane key="1" title="账号登录">
|
<a-tab-pane key="1" title="账号登录">
|
||||||
<component :is="AccountLogin" v-if="activeTab === '1'" />
|
<component :is="AccountLogin" v-if="activeTab === '1'" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
@ -73,19 +56,6 @@
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<div class="login-right__oauth">
|
|
||||||
<a-divider orientation="center">其他登录方式</a-divider>
|
|
||||||
<div class="list">
|
|
||||||
<div v-if="isEmailLogin" class="mode item" @click="toggleLoginMode"><icon-user /> 账号/手机号登录</div>
|
|
||||||
<div v-else class="mode item" @click="toggleLoginMode"><icon-email /> 邮箱登录</div>
|
|
||||||
<a class="item" title="使用 Gitee 账号登录" @click="onOauth('gitee')">
|
|
||||||
<GiSvgIcon name="gitee" :size="24" />
|
|
||||||
</a>
|
|
||||||
<a class="item" title="使用 GitHub 账号登录" @click="onOauth('github')">
|
|
||||||
<GiSvgIcon name="github" :size="24" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -94,8 +64,6 @@ import { computed, ref } from 'vue'
|
||||||
import Background from './components/background/index.vue'
|
import Background from './components/background/index.vue'
|
||||||
import AccountLogin from './components/account/index.vue'
|
import AccountLogin from './components/account/index.vue'
|
||||||
import PhoneLogin from './components/phone/index.vue'
|
import PhoneLogin from './components/phone/index.vue'
|
||||||
import EmailLogin from './components/email/index.vue'
|
|
||||||
import { socialAuth } from '@/apis/auth'
|
|
||||||
import { useAppStore } from '@/stores'
|
import { useAppStore } from '@/stores'
|
||||||
import { useDevice } from '@/hooks'
|
import { useDevice } from '@/hooks'
|
||||||
|
|
||||||
|
@ -106,19 +74,7 @@ const appStore = useAppStore()
|
||||||
const title = computed(() => appStore.getTitle())
|
const title = computed(() => appStore.getTitle())
|
||||||
const logo = computed(() => appStore.getLogo())
|
const logo = computed(() => appStore.getLogo())
|
||||||
|
|
||||||
const isEmailLogin = ref(false)
|
|
||||||
const activeTab = ref('1')
|
const activeTab = ref('1')
|
||||||
|
|
||||||
// 切换登录模式
|
|
||||||
const toggleLoginMode = () => {
|
|
||||||
isEmailLogin.value = !isEmailLogin.value
|
|
||||||
}
|
|
||||||
|
|
||||||
// 第三方登录授权
|
|
||||||
const onOauth = async (source: string) => {
|
|
||||||
const { data } = await socialAuth(source)
|
|
||||||
window.location.href = data.authorizeUrl
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -217,66 +173,7 @@ const onOauth = async (source: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__oauth {
|
|
||||||
width: 100%;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
|
|
||||||
// margin-top: auto;
|
|
||||||
// margin-bottom: 20px;
|
|
||||||
:deep(.arco-divider-text) {
|
|
||||||
color: var(--color-text-4);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode {
|
|
||||||
color: var(--color-text-2);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 20px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
align-items: center;
|
|
||||||
border: 1px solid var(--color-border-3);
|
|
||||||
border-radius: 32px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
height: 32px;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 21px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode svg {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode:hover,
|
|
||||||
.mode svg:hover {
|
|
||||||
background: rgba(var(--primary-6), 0.05);
|
|
||||||
border: 1px solid rgb(var(--primary-3));
|
|
||||||
color: rgb(var(--arcoblue-6));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-btn {
|
.theme-btn {
|
||||||
|
@ -429,60 +326,7 @@ const onOauth = async (source: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__oauth {
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
:deep(.arco-divider-text) {
|
|
||||||
color: var(--color-text-4);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode {
|
|
||||||
color: var(--color-text-2);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 20px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
align-items: center;
|
|
||||||
border: 1px solid var(--color-border-3);
|
|
||||||
border-radius: 32px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
height: 32px;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 21px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode svg {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mode:hover {
|
|
||||||
background: rgba(var(--primary-6), 0.05);
|
|
||||||
border: 1px solid rgb(var(--primary-3));
|
|
||||||
color: rgb(var(--arcoblue-6));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-btn {
|
.theme-btn {
|
||||||
|
|
Loading…
Reference in New Issue