fix: complete auth token lifecycle

This commit is contained in:
rain
2026-07-11 09:29:17 +08:00
parent 68f72eb960
commit 8b896f4ba3
2 changed files with 65 additions and 13 deletions
+51 -8
View File
@@ -28,7 +28,7 @@ async function run() {
assert.strictEqual(GenealogyApi.DEFAULT_BASE_URL, undefined); assert.strictEqual(GenealogyApi.DEFAULT_BASE_URL, undefined);
const client = GenealogyApi.createClient({ const client = GenealogyApi.createClient({
baseUrl: 'https://test-genealogy-api.ddxcjp.cn', baseUrl: 'http://182.61.18.23:8080',
clientId: 'client-x', clientId: 'client-x',
tenantId: 'tenant-x', tenantId: 'tenant-x',
tokenKey: 'token-key', tokenKey: 'token-key',
@@ -136,7 +136,7 @@ async function run() {
'token-key': 'existing-token' 'token-key': 'existing-token'
}); });
const failedRegisterClient = GenealogyApi.createClient({ const failedRegisterClient = GenealogyApi.createClient({
baseUrl: 'https://test-genealogy-api.ddxcjp.cn', baseUrl: 'http://182.61.18.23:8080',
clientId: 'client-x', clientId: 'client-x',
tenantId: 'tenant-x', tenantId: 'tenant-x',
tokenKey: 'token-key', tokenKey: 'token-key',
@@ -158,16 +158,59 @@ async function run() {
); );
assert.strictEqual(failedRegisterStore.getItem('token-key'), 'existing-token'); assert.strictEqual(failedRegisterStore.getItem('token-key'), 'existing-token');
const missingTokenStore = createStore();
const missingTokenClient = GenealogyApi.createClient({
baseUrl: 'http://182.61.18.23:8080',
clientId: 'client-x',
tenantId: 'tenant-x',
tokenKey: 'token-key',
tokenStore: missingTokenStore,
axiosInstance: {
request: async () => ({
status: 200,
data: { code: 200, data: {} }
})
}
});
await assert.rejects(
missingTokenClient.login({ phone: '13800000000', password: 'md5' }),
(error) => error.message === '登录响应缺少 token'
);
assert.strictEqual(missingTokenStore.getItem('token-key'), null);
store.setItem('token-key', 'logout-token');
await client.logout();
assert.strictEqual(calls[9].url, '/genealogy/pc/auth/logout');
assert.strictEqual(store.getItem('token-key'), null);
const failedLogoutStore = createStore({
'token-key': 'logout-token'
});
const failedLogoutClient = GenealogyApi.createClient({
baseUrl: 'http://182.61.18.23:8080',
clientId: 'client-x',
tenantId: 'tenant-x',
tokenKey: 'token-key',
tokenStore: failedLogoutStore,
axiosInstance: {
request: async () => {
throw new Error('logout failed');
}
}
});
await assert.rejects(failedLogoutClient.logout(), /logout failed/);
assert.strictEqual(failedLogoutStore.getItem('token-key'), null);
await client.sendSmsCode({ await client.sendSmsCode({
sceneCode: 'WEB_H5_LOGIN', sceneCode: 'WEB_H5_LOGIN',
phone: '13800000000', phone: '13800000000',
validToken: 'captcha-ticket' validToken: 'captcha-ticket'
}); });
assert.strictEqual(calls[9].url, '/genealogy/pc/auth/sms/code'); assert.strictEqual(calls[10].url, '/genealogy/pc/auth/sms/code');
assert.strictEqual(calls[9].headers.Authorization, undefined); assert.strictEqual(calls[10].headers.Authorization, undefined);
assert.strictEqual(calls[9].data.grantType, 'sms'); assert.strictEqual(calls[10].data.grantType, 'sms');
assert.strictEqual(calls[9].data.sceneCode, 'WEB_H5_LOGIN'); assert.strictEqual(calls[10].data.sceneCode, 'WEB_H5_LOGIN');
assert.strictEqual(calls[9].data.validToken, 'captcha-ticket'); assert.strictEqual(calls[10].data.validToken, 'captcha-ticket');
assert.throws( assert.throws(
() => client.listGenealogies(), () => client.listGenealogies(),
@@ -177,7 +220,7 @@ async function run() {
() => client.publicGenealogies(), () => client.publicGenealogies(),
(error) => error.code === 'PC_API_NOT_AVAILABLE' (error) => error.code === 'PC_API_NOT_AVAILABLE'
); );
assert.strictEqual(calls.length, 10); assert.strictEqual(calls.length, 11);
console.log('api-client tests passed'); console.log('api-client tests passed');
} }
+14 -5
View File
@@ -55,6 +55,13 @@
return data.token || data.accessToken || data.tokenValue || ''; return data.token || data.accessToken || data.tokenValue || '';
} }
function requireLoginToken(data) {
var token = getTokenFromResponse(data);
if (!token) throw new ApiError('登录响应缺少 token');
return token;
}
function ApiError(message, options) { function ApiError(message, options) {
this.name = 'ApiError'; this.name = 'ApiError';
this.message = message || '接口请求失败'; this.message = message || '接口请求失败';
@@ -169,7 +176,7 @@
auth: false, auth: false,
body: Object.assign({ grantType: 'password' }, withTenant(body)) body: Object.assign({ grantType: 'password' }, withTenant(body))
}); });
setToken(getTokenFromResponse(data)); setToken(requireLoginToken(data));
return data; return data;
} }
@@ -187,7 +194,7 @@
auth: false, auth: false,
body: Object.assign({ grantType: 'sms' }, withTenant(body)) body: Object.assign({ grantType: 'sms' }, withTenant(body))
}); });
setToken(getTokenFromResponse(data)); setToken(requireLoginToken(data));
return data; return data;
} }
@@ -267,9 +274,11 @@
return data; return data;
}, },
logout: async function () { logout: async function () {
var data = await request('DELETE', '/genealogy/pc/auth/logout'); try {
clearToken(); return await request('DELETE', '/genealogy/pc/auth/logout');
return data; } finally {
clearToken();
}
}, },
uploadFile: function (fileOrFormData) { uploadFile: function (fileOrFormData) {
return request('POST', '/genealogy/pc/files/upload', { body: createFormData(fileOrFormData) }); return request('POST', '/genealogy/pc/files/upload', { body: createFormData(fileOrFormData) });