fix: infinite login loop from async auth validation
- Add _validating flag to prevent recursive hashchange calls during async token validation - route() checks _validating before calling validateAuth(), sets flag before async call, clears in .then/.catch handlers - route() returns early if still validating (waits for completion) - Fixes: expired token causing infinite login redirect loop
This commit is contained in:
@@ -95,13 +95,19 @@ const App = {
|
|||||||
closeModal() { document.getElementById('modal-overlay').classList.add('hidden'); },
|
closeModal() { document.getElementById('modal-overlay').classList.add('hidden'); },
|
||||||
navigate(page, param) { location.hash = `#/${page}` + (param ? `/${param}` : ''); },
|
navigate(page, param) { location.hash = `#/${page}` + (param ? `/${param}` : ''); },
|
||||||
|
|
||||||
|
_validating: false,
|
||||||
|
|
||||||
// 验证 token 有效性(轻量级,失败则清除登录态)
|
// 验证 token 有效性(轻量级,失败则清除登录态)
|
||||||
async validateAuth() {
|
async validateAuth() {
|
||||||
if (!Auth.logged()) return false;
|
if (this._validating) return null; // 防止递归
|
||||||
|
this._validating = true;
|
||||||
|
if (!Auth.logged()) { this._validating = false; return false; }
|
||||||
try {
|
try {
|
||||||
await API.get('/me');
|
await API.get('/me');
|
||||||
|
this._validating = false;
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
this._validating = false;
|
||||||
if (e && e.message && e.message.includes('登录')) {
|
if (e && e.message && e.message.includes('登录')) {
|
||||||
Auth.reset();
|
Auth.reset();
|
||||||
return false;
|
return false;
|
||||||
@@ -126,17 +132,27 @@ const App = {
|
|||||||
if (page === 'login' || page === 'register' || page === 'forgot' || page === 'reset') { this.showPublic(page); return; }
|
if (page === 'login' || page === 'register' || page === 'forgot' || page === 'reset') { this.showPublic(page); return; }
|
||||||
|
|
||||||
// 访问受保护页面前先验证 token 有效性
|
// 访问受保护页面前先验证 token 有效性
|
||||||
if (Auth.logged()) {
|
if (Auth.logged() && !this._validating) {
|
||||||
|
this._validating = true; // 标记正在验证
|
||||||
this.validateAuth().then(valid => {
|
this.validateAuth().then(valid => {
|
||||||
if (!valid) { location.hash = '#/login'; return; }
|
this._validating = false;
|
||||||
|
if (!valid) {
|
||||||
|
location.hash = '#/login';
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._doRoute(page, param);
|
this._doRoute(page, param);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
this._validating = false;
|
||||||
Auth.reset();
|
Auth.reset();
|
||||||
location.hash = '#/login';
|
location.hash = '#/login';
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!Auth.logged()) {
|
||||||
location.hash = '#/login';
|
location.hash = '#/login';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 正在验证中,不做任何操作(等待验证完成)
|
||||||
},
|
},
|
||||||
|
|
||||||
_doRoute(page, param) {
|
_doRoute(page, param) {
|
||||||
|
|||||||
Reference in New Issue
Block a user