feat: 增加环境切换
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { getApiConfig } from '../config/api';
|
||||
import { getApiConfig, apiContextKey, isCurrentApiConfig } from '../config/api';
|
||||
import { ApiRequestError, requestApi } from './api-transport';
|
||||
|
||||
export interface ServerUser {
|
||||
@@ -32,7 +32,7 @@ export function getAuthContext() {
|
||||
if (!appId) throw new ApiRequestError('无法识别小程序身份');
|
||||
return {
|
||||
...config,
|
||||
key: `doodle_auth_v1:${encodeURIComponent(appId)}:${encodeURIComponent(config.baseUrl)}`,
|
||||
key: `doodle_auth_v2:${apiContextKey(config)}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,7 +70,18 @@ function readState(context: Context): SessionState {
|
||||
generation: 0,
|
||||
};
|
||||
try {
|
||||
const stored = wx.getStorageSync(context.key);
|
||||
// 旧版会话只迁入原默认环境,不能复制到同址的 staging/production 开发配置。
|
||||
const legacyDefault =
|
||||
context.version === 'develop'
|
||||
? context.environment === 'local'
|
||||
: context.environment === 'production';
|
||||
const stored =
|
||||
wx.getStorageSync(context.key) ||
|
||||
(legacyDefault
|
||||
? wx.getStorageSync(
|
||||
`doodle_auth_v1:${encodeURIComponent(wx.getAccountInfoSync().miniProgram.appId)}:${encodeURIComponent(context.baseUrl)}`,
|
||||
)
|
||||
: null);
|
||||
if (stored) {
|
||||
state.history = 'used';
|
||||
if (
|
||||
@@ -145,7 +156,7 @@ export async function ensureSession(
|
||||
force = false,
|
||||
explicitStart = false,
|
||||
): Promise<AuthSession> {
|
||||
if (getAuthContext().key !== context.key)
|
||||
if (!isCurrentApiConfig(context))
|
||||
throw new ApiRequestError('接口环境已变化,请重新操作');
|
||||
const state = readState(context);
|
||||
if (state.history === 'blocked' && !explicitStart)
|
||||
@@ -184,11 +195,13 @@ export async function ensureSession(
|
||||
);
|
||||
break;
|
||||
} catch (error) {
|
||||
if (!(
|
||||
error instanceof ApiRequestError &&
|
||||
error.reason === 'WECHAT_CODE_INVALID' &&
|
||||
attempt === 0
|
||||
))
|
||||
if (
|
||||
!(
|
||||
error instanceof ApiRequestError &&
|
||||
error.reason === 'WECHAT_CODE_INVALID' &&
|
||||
attempt === 0
|
||||
)
|
||||
)
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -210,10 +223,7 @@ export async function ensureSession(
|
||||
user: parseServerUser(result.user),
|
||||
};
|
||||
// 清理、切换环境期间迟到的登录响应不得恢复会话或写入当前界面。
|
||||
if (
|
||||
state.generation !== generation ||
|
||||
getAuthContext().key !== context.key
|
||||
)
|
||||
if (state.generation !== generation || !isCurrentApiConfig(context))
|
||||
throw new ApiRequestError('登录状态已变化,请重新操作');
|
||||
state.session = session;
|
||||
state.history = 'used';
|
||||
@@ -222,6 +232,7 @@ export async function ensureSession(
|
||||
} catch (error) {
|
||||
if (
|
||||
state.generation === generation &&
|
||||
isCurrentApiConfig(context) &&
|
||||
error instanceof ApiRequestError &&
|
||||
[
|
||||
'ACCOUNT_NOT_FOUND',
|
||||
@@ -244,6 +255,14 @@ export async function ensureSession(
|
||||
}
|
||||
}
|
||||
|
||||
/** 保留各环境已保存会话和账户历史,只作废尚未完成的登录任务。 */
|
||||
export function invalidatePendingAuthentication() {
|
||||
for (const state of states.values()) {
|
||||
state.generation++;
|
||||
state.flight = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/** 同一原请求只恢复一次;迟到的旧 401 直接复用较新凭证。 */
|
||||
export async function recoverSession(context: Context, failed: AuthSession) {
|
||||
const state = readState(context);
|
||||
|
||||
Reference in New Issue
Block a user