fix(mobile): harden stored auth credentials and login response validation
- Treat 'undefined'/'null' localStorage values as absent; clear incomplete token/clientId pairs and prompt re-login instead of sending broken headers - Gate authenticated UI on both token and clientId via isAuthenticated - Reject login responses missing access_token or client_id
This commit is contained in:
+25
-8
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<main class="mobile-aihr">
|
<main class="mobile-aihr">
|
||||||
<section v-if="!authToken" class="page auth-page">
|
<section v-if="!isAuthenticated" class="page auth-page">
|
||||||
<header class="top auth-top">
|
<header class="top auth-top">
|
||||||
<div class="top-row">
|
<div class="top-row">
|
||||||
<h1>AI人力助手</h1>
|
<h1>AI人力助手</h1>
|
||||||
@@ -1604,6 +1604,17 @@ const tokenKey = 'aihr_mobile_access_token';
|
|||||||
const clientIdKey = 'aihr_mobile_client_id';
|
const clientIdKey = 'aihr_mobile_client_id';
|
||||||
const phoneKey = 'aihr_mobile_phone';
|
const phoneKey = 'aihr_mobile_phone';
|
||||||
const phonePattern = /^1[3-9]\d{9}$/;
|
const phonePattern = /^1[3-9]\d{9}$/;
|
||||||
|
const readStoredCredential = (key: string) => {
|
||||||
|
const value = localStorage.getItem(key)?.trim() || '';
|
||||||
|
return value === 'undefined' || value === 'null' ? '' : value;
|
||||||
|
};
|
||||||
|
const initialAuthToken = readStoredCredential(tokenKey);
|
||||||
|
const initialClientId = readStoredCredential(clientIdKey);
|
||||||
|
const hasIncompleteStoredAuth = Boolean(initialAuthToken || initialClientId) && !(initialAuthToken && initialClientId);
|
||||||
|
if (hasIncompleteStoredAuth) {
|
||||||
|
localStorage.removeItem(tokenKey);
|
||||||
|
localStorage.removeItem(clientIdKey);
|
||||||
|
}
|
||||||
const practiceScenarios: PracticeScenario[] = [
|
const practiceScenarios: PracticeScenario[] = [
|
||||||
{
|
{
|
||||||
id: 'complaint-water',
|
id: 'complaint-water',
|
||||||
@@ -1668,9 +1679,10 @@ const tapped = ref('');
|
|||||||
const toastMessage = ref('');
|
const toastMessage = ref('');
|
||||||
const phone = ref(localStorage.getItem(phoneKey) || '');
|
const phone = ref(localStorage.getItem(phoneKey) || '');
|
||||||
const smsCode = ref('');
|
const smsCode = ref('');
|
||||||
const authToken = ref(localStorage.getItem(tokenKey) || '');
|
const authToken = ref(hasIncompleteStoredAuth ? '' : initialAuthToken);
|
||||||
const clientId = ref(localStorage.getItem(clientIdKey) || '');
|
const clientId = ref(hasIncompleteStoredAuth ? '' : initialClientId);
|
||||||
const authMessage = ref('');
|
const authMessage = ref(hasIncompleteStoredAuth ? '登录已过期,请重新登录' : '');
|
||||||
|
const isAuthenticated = computed(() => Boolean(authToken.value && clientId.value));
|
||||||
const sendingCode = ref(false);
|
const sendingCode = ref(false);
|
||||||
const loggingIn = ref(false);
|
const loggingIn = ref(false);
|
||||||
const practiceStatus = ref<PracticeStatus>('idle');
|
const practiceStatus = ref<PracticeStatus>('idle');
|
||||||
@@ -3364,10 +3376,15 @@ const loginBySms = async () => {
|
|||||||
body: JSON.stringify({ phonenumber: phone.value, smsCode: smsCode.value, tenantId: '000000' })
|
body: JSON.stringify({ phonenumber: phone.value, smsCode: smsCode.value, tenantId: '000000' })
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
authToken.value = data.access_token;
|
const nextToken = data.access_token?.trim() || '';
|
||||||
clientId.value = data.client_id;
|
const nextClientId = data.client_id?.trim() || '';
|
||||||
localStorage.setItem(tokenKey, data.access_token);
|
if (!nextToken || !nextClientId) {
|
||||||
localStorage.setItem(clientIdKey, data.client_id);
|
throw new Error('登录响应缺少认证信息,请重试');
|
||||||
|
}
|
||||||
|
authToken.value = nextToken;
|
||||||
|
clientId.value = nextClientId;
|
||||||
|
localStorage.setItem(tokenKey, nextToken);
|
||||||
|
localStorage.setItem(clientIdKey, nextClientId);
|
||||||
localStorage.setItem(phoneKey, phone.value);
|
localStorage.setItem(phoneKey, phone.value);
|
||||||
smsCode.value = '';
|
smsCode.value = '';
|
||||||
void fetchMobileHome();
|
void fetchMobileHome();
|
||||||
|
|||||||
Reference in New Issue
Block a user