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>
|
||||
<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">
|
||||
<div class="top-row">
|
||||
<h1>AI人力助手</h1>
|
||||
@@ -1604,6 +1604,17 @@ const tokenKey = 'aihr_mobile_access_token';
|
||||
const clientIdKey = 'aihr_mobile_client_id';
|
||||
const phoneKey = 'aihr_mobile_phone';
|
||||
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[] = [
|
||||
{
|
||||
id: 'complaint-water',
|
||||
@@ -1668,9 +1679,10 @@ const tapped = ref('');
|
||||
const toastMessage = ref('');
|
||||
const phone = ref(localStorage.getItem(phoneKey) || '');
|
||||
const smsCode = ref('');
|
||||
const authToken = ref(localStorage.getItem(tokenKey) || '');
|
||||
const clientId = ref(localStorage.getItem(clientIdKey) || '');
|
||||
const authMessage = ref('');
|
||||
const authToken = ref(hasIncompleteStoredAuth ? '' : initialAuthToken);
|
||||
const clientId = ref(hasIncompleteStoredAuth ? '' : initialClientId);
|
||||
const authMessage = ref(hasIncompleteStoredAuth ? '登录已过期,请重新登录' : '');
|
||||
const isAuthenticated = computed(() => Boolean(authToken.value && clientId.value));
|
||||
const sendingCode = ref(false);
|
||||
const loggingIn = ref(false);
|
||||
const practiceStatus = ref<PracticeStatus>('idle');
|
||||
@@ -3364,10 +3376,15 @@ const loginBySms = async () => {
|
||||
body: JSON.stringify({ phonenumber: phone.value, smsCode: smsCode.value, tenantId: '000000' })
|
||||
})
|
||||
);
|
||||
authToken.value = data.access_token;
|
||||
clientId.value = data.client_id;
|
||||
localStorage.setItem(tokenKey, data.access_token);
|
||||
localStorage.setItem(clientIdKey, data.client_id);
|
||||
const nextToken = data.access_token?.trim() || '';
|
||||
const nextClientId = data.client_id?.trim() || '';
|
||||
if (!nextToken || !nextClientId) {
|
||||
throw new Error('登录响应缺少认证信息,请重试');
|
||||
}
|
||||
authToken.value = nextToken;
|
||||
clientId.value = nextClientId;
|
||||
localStorage.setItem(tokenKey, nextToken);
|
||||
localStorage.setItem(clientIdKey, nextClientId);
|
||||
localStorage.setItem(phoneKey, phone.value);
|
||||
smsCode.value = '';
|
||||
void fetchMobileHome();
|
||||
|
||||
Reference in New Issue
Block a user