修改密码加密

This commit is contained in:
游离 2025-06-30 17:51:39 +08:00
parent 41b9474300
commit 3378ab4a49
7 changed files with 24 additions and 188 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -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')
} }

View File

@ -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'),

View File

@ -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,

View File

@ -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, {

View File

@ -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

View File

@ -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 {