From f358e0d26a7ea53f3d1011fa85e82e603b02148a Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Sat, 28 Sep 2024 00:21:30 +0800 Subject: [PATCH] :sparkles: add api validation signature --- src/api/captcha/index.ts | 19 ------ src/api/user/index.ts | 38 ++++++------ src/types/user.d.ts | 2 + src/utils/alova/service.ts | 10 ++++ src/utils/signature/signature.ts | 33 +++++++++++ src/views/Forget/ForgetPage.vue | 39 ++++--------- src/views/Login/LoginPage.vue | 99 ++++++++++++-------------------- src/views/Main/MainPage.vue | 12 ++-- 8 files changed, 122 insertions(+), 130 deletions(-) create mode 100644 src/utils/signature/signature.ts diff --git a/src/api/captcha/index.ts b/src/api/captcha/index.ts index 0e04928..fac5fe9 100644 --- a/src/api/captcha/index.ts +++ b/src/api/captcha/index.ts @@ -9,25 +9,6 @@ export const getRotatedCaptchaData = () => { ignoreToken: true }, }); - -}; -/** - * 验证验证码 - * @param angle - * @param key - */ -export const checkRotatedCaptcha = (angle: any, key: any) => { - return service.Post('/api/captcha/rotate/check', { - angle: angle, - key: key, - }, - { - meta: { - ignoreToken: true - }, - } - ); - }; /** * 获取滑动验证码图片数据 diff --git a/src/api/user/index.ts b/src/api/user/index.ts index ea63288..847796e 100644 --- a/src/api/user/index.ts +++ b/src/api/user/index.ts @@ -35,17 +35,20 @@ export const refreshToken = (refreshToken: string) => { }; /** * 发送短信验证码 - * @param phone + * @param params */ -export const sendMessage = (phone: string) => { - return service.Get('/api/sms/test/send', { - params: { - phone: phone +export const sendMessage = (params: any) => { + return service.Post('/api/sms/test/send', { + phone: params.phone, + angle: params.angle, + key: params.key, }, - meta: { - ignoreToken: true + { + meta: { + ignoreToken: true + } } - }); + ); }; /** * 手机登录 @@ -73,7 +76,9 @@ export const accountLoginApi = (param: AccountLogin) => { return service.Post('/api/user/login', { account: param.account, password: param.password, - auto_login: param.auto_login + auto_login: param.auto_login, + angle: param.angle, + key: param.key, }, { meta: { @@ -106,13 +111,14 @@ export const resetPasswordApi = (param: ResetPassword) => { * @param user_id */ export const getUserPermissions = (user_id: string) => { - return service.Get('/api/auth/permission/get_user_permissions', { - params: { + return service.Post('/api/auth/permission/get_user_permissions', { user_id: user_id }, - meta: { - ignoreToken: false, + { + meta: { + ignoreToken: false, + } } - } - ); -}; + ); + } +; diff --git a/src/types/user.d.ts b/src/types/user.d.ts index 406c015..2dbb43c 100644 --- a/src/types/user.d.ts +++ b/src/types/user.d.ts @@ -2,6 +2,8 @@ export interface AccountLogin { account?: string password?: string; auto_login?: boolean; + angle: number, + key: string, } export interface PhoneLogin { diff --git a/src/utils/alova/service.ts b/src/utils/alova/service.ts index 16dbfb2..7ac2cb4 100644 --- a/src/utils/alova/service.ts +++ b/src/utils/alova/service.ts @@ -10,6 +10,7 @@ import {message, Modal} from "ant-design-vue"; import i18n from "@/locales"; import {axiosRequestAdapter} from "@alova/adapter-axios"; import {refreshToken} from "@/api/user"; +import createMD5Signature, {generateNonce} from "@/utils/signature/signature.ts"; let hasShownNetworkError: boolean = false; const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication(false); -const captchaErrorCount = ref(0); const resetPasswordRotateEvent = { confirm: (angle: number) => { checkPhoneLoginCaptcha(angle); @@ -293,9 +292,8 @@ async function getRotateCaptcha() { /** * 发送手机验证码 */ -async function sendMessageByPhone(): Promise { - const phone: string = ResetPasswordForm.phone as string; - const res: any = await sendMessage(phone); +async function sendMessageByPhone(param: any): Promise { + const res: any = await sendMessage(param); if (res.code === 200 && res.success) { message.success(t('login.sendCaptchaSuccess')); return true; @@ -310,28 +308,15 @@ async function sendMessageByPhone(): Promise { * @param angle */ async function checkPhoneLoginCaptcha(angle: number) { - if (captchaErrorCount.value >= 2) { - message.error(t('login.captchaError')); - getRotateCaptcha().then(() => { - captchaErrorCount.value = 0; - }); - } else { - const result: any = await checkRotatedCaptcha(angle, captchaData.key); - if (result.code === 200 && result.success) { - showRotateCaptcha.value = false; - const result: boolean = await sendMessageByPhone(); - if (result) { - countDown(); - } - } else if (result.code === 1011) { - message.error(t('login.captchaExpired')); - getRotateCaptcha().then(() => { - captchaErrorCount.value = 0; - }); - } else { - captchaErrorCount.value++; - message.error(t('login.captchaError')); - } + const param = { + key: captchaData.key, + angle: angle, + phone: ResetPasswordForm.phone, + }; + const result: boolean = await sendMessageByPhone(param); + if (result) { + showRotateCaptcha.value = false; + countDown(); } } diff --git a/src/views/Login/LoginPage.vue b/src/views/Login/LoginPage.vue index 2ddb8c4..5153954 100644 --- a/src/views/Login/LoginPage.vue +++ b/src/views/Login/LoginPage.vue @@ -193,7 +193,7 @@ import {useI18n} from "vue-i18n"; import BoxDog from "@/components/BoxDog/BoxDog.vue"; import LoginFooter from "@/views/Login/LoginFooter.vue"; import {useRouter} from "vue-router"; -import {checkRotatedCaptcha, getRotatedCaptchaData} from "@/api/captcha"; +import {getRotatedCaptchaData} from "@/api/captcha"; import {message} from "ant-design-vue"; import {accountLoginApi, phoneLoginApi, sendMessage} from "@/api/user"; import useStore from "@/store"; @@ -206,7 +206,6 @@ const phoneLoginFormRef = ref(); const showPhoneRotateCaptcha = ref(false); const showAccountRotateCaptcha = ref(false); const captchaData = reactive({angle: 0, image: "", thumb: "", key: ""}); -const captchaErrorCount = ref(0); const loginLoading = ref(false); const phoneLoginRotateEvent = { confirm: (angle: number) => { @@ -235,6 +234,8 @@ const accountLoginForm: UnwrapRef = reactive({ account: '', password: '', auto_login: true, + angle: 0, + key: "", }); // 手机登录表单数据 const phoneLoginForm: UnwrapRef = reactive({ @@ -429,28 +430,15 @@ const checkPhoneLoginCaptchaDebounce = useDebounceFn(checkPhoneLoginCaptcha, 500 * @param angle */ async function checkPhoneLoginCaptcha(angle: number) { - if (captchaErrorCount.value >= 2) { - message.error(t('login.captchaError')); - getRotateCaptcha().then(() => { - captchaErrorCount.value = 0; - }); - } else { - const result: any = await checkRotatedCaptcha(angle, captchaData.key); - if (result.code === 200 && result.success) { - showPhoneRotateCaptcha.value = false; - const result: boolean = await sendMessageByPhone(); - if (result) { - countDown(); - } - } else if (result.code === 1011) { - message.error(t('login.captchaExpired')); - getRotateCaptcha().then(() => { - captchaErrorCount.value = 0; - }); - } else { - captchaErrorCount.value++; - message.error(t('login.captchaError')); - } + const params = { + phone: phoneLoginForm.phone, + angle: angle, + key: captchaData.key, + }; + const result: boolean = await sendMessageByPhone(params); + if (result) { + showPhoneRotateCaptcha.value = false; + countDown(); } } @@ -464,51 +452,38 @@ const checkAccountLoginCaptchaDebounce = useDebounceFn(checkAccountLoginCaptcha, * @param angle */ async function checkAccountLoginCaptcha(angle: number) { - if (captchaErrorCount.value >= 2) { - message.error(t('login.captchaError')); - getRotateCaptcha().then(() => { - captchaErrorCount.value = 0; - }); + const params = { + ...accountLoginForm, + angle: angle, + key: captchaData.key, + }; + loginLoading.value = true; + const res: any = await accountLoginApi(params); + if (res.code === 200 && res.success) { + const userStore = useStore().user; + const {uid, access_token, refresh_token, expires_at} = res.data; + userStore.user.uid = uid; + userStore.user.accessToken = access_token; + userStore.user.refreshToken = refresh_token; + userStore.user.expiresAt = expires_at; + message.success(t('login.loginSuccess')); + loginLoading.value = false; + showAccountRotateCaptcha.value = false; + setTimeout(() => { + router.push('/main'); + }, 1000); } else { - const result: any = await checkRotatedCaptcha(angle, captchaData.key); - if (result.code === 200 && result.success) { - showAccountRotateCaptcha.value = false; - loginLoading.value = true; - const res: any = await accountLoginApi(accountLoginForm); - if (res.code === 200 && res.success) { - const userStore = useStore().user; - const {uid, access_token, refresh_token, expires_at} = res.data; - userStore.user.uid = uid; - userStore.user.accessToken = access_token; - userStore.user.refreshToken = refresh_token; - userStore.user.expiresAt = expires_at; - message.success(t('login.loginSuccess')); - loginLoading.value = false; - setTimeout(() => { - router.push('/main'); - }, 1000); - } else { - loginLoading.value = false; - message.error(t('login.loginError')); - } - } else if (result.code === 1011) { - message.error(t('login.captchaExpired')); - getRotateCaptcha().then(() => { - captchaErrorCount.value = 0; - }); - } else { - captchaErrorCount.value++; - message.error(t('login.captchaError')); - } + loginLoading.value = false; + message.error(t('login.loginError')); } + } /** * 发送手机验证码 */ -async function sendMessageByPhone(): Promise { - const phone: string = phoneLoginForm.phone as string; - const res: any = await sendMessage(phone); +async function sendMessageByPhone(params: any): Promise { + const res: any = await sendMessage(params); if (res.code === 200 && res.success) { message.success(t('login.sendCaptchaSuccess')); return true; diff --git a/src/views/Main/MainPage.vue b/src/views/Main/MainPage.vue index 57295b1..a36e3af 100644 --- a/src/views/Main/MainPage.vue +++ b/src/views/Main/MainPage.vue @@ -33,12 +33,12 @@ const wsOptions = { onMounted(() => { websocket.initialize(wsOptions); websocket.on("message", async (data: any) => { - notification.open({ - message: '消息来了', - description: - data, - icon: () => h(SmileOutlined, {style: 'color: #108ee9'}), - }); + // notification.open({ + // message: '消息来了', + // description: + // data, + // icon: () => h(SmileOutlined, {style: 'color: #108ee9'}), + // }); }); });