diff --git a/apps/api/src/modules/org/internal/adapter/keycloak-token-verifier.ts b/apps/api/src/modules/org/internal/adapter/keycloak-token-verifier.ts index ba475e3..06c6795 100644 --- a/apps/api/src/modules/org/internal/adapter/keycloak-token-verifier.ts +++ b/apps/api/src/modules/org/internal/adapter/keycloak-token-verifier.ts @@ -46,7 +46,12 @@ function toVerifiedClaims(claims: z.infer): VerifiedClaims }; } -/** jose 的错误 → 人话(手册 4.4)。JWTExpired 是 JWTClaimValidationFailed 的子类,先判它 */ +/** + * jose 的错误 → 人话(手册 4.4)。 + * 两者都直接继承自 `JOSEError`:类型声明上 `JWTExpired implements JWTClaimValidationFailed`, + * 但运行时**没有**继承关系(`implements` 只是结构化类型)。这里判在前不是因为父子, + * 而是要让「已过期」这条更具体的话先命中 —— 顺序是给人看的,不是给 instanceof 兜底的。 + */ export function explainJoseError(error: unknown, ctx: { readonly issuer: string; readonly audience: string }): string { if (error instanceof joseErrors.JWTExpired) return 'token 已过期,用 refresh_token 换个新的'; if (error instanceof joseErrors.JWTClaimValidationFailed) {