Browse Source

refactor(auth): 鉴权域整体硬切真实后端,移除 mock 分支

- sendSmsCode / loginByPassword / loginBySms / fetchCurrentUser 等不再受全局
  isMockMode() 控制,永远走真实接口;mockAuthTokens 辅助函数随之删除
- 鉴权链路(短信、/auth/login、/auth/me、/auth/refresh、/auth/logout、
  /auth/identity/select、/auth/company/register)均已实网验证
- sendSmsCode 失败改为向上抛出,由 useSmsCode 在页面提示(原先静默返回会
  让用户以为验证码已发出)
- 业务域未接通部分仍按 isMockMode 兜底 mock,行为不变
master
doublex001 4 weeks ago
parent
commit
6d8487a11f
  1. 76
      src/api/auth.ts

76
src/api/auth.ts

@ -1,9 +1,15 @@
import { request, isMockMode, toExpiresAt } from './http'; import { request, toExpiresAt } from './http';
import type { AppRole } from '../types'; import type { AppRole } from '../types';
/* ===================== 鉴权接口(真实后端) ===================== /* ===================== 鉴权接口(真实后端 · 不走 mock) =====================
* 落实规范第 4、5、6 节。全部走 http 层;匿名接口显式 auth:false。 * 落实规范第 4、5、6 节。全部走 http 层;匿名接口显式 auth:false。
* 客户端不提交 role / userId / verified / passwordHash(后端生成)。 * 客户端不提交 role / userId / verified / passwordHash(后端生成)。
*
* 鉴权域已整体切真实后端(2026-09-30):短信网关、/auth/login、/auth/me、
* /auth/refresh、/auth/logout、/auth/identity/select、/auth/company/register
* 均已接通。本文件函数不再受全局 isMockMode() 控制,永远走真实接口;
* 业务域(api.ts 内未接通的接口)仍按 isMockMode 兜底 mock。
* 故 mockAuthTokens 辅助函数已删除——鉴权域不再有 mock 形态。
*/ */
/** /**
@ -75,12 +81,11 @@ function isValidPhone(phone: string): boolean {
return /^1[3-9]\d{9}$/.test(phone); return /^1[3-9]\d{9}$/.test(phone);
} }
/** 发送短信验证码(§4 步骤1 / §6 步骤1) */ /** 发送短信验证码(§4 步骤1 / §6 步骤1):失败抛出,由 useSmsCode 在页面提示 */
export async function sendSmsCode(payload: SmsSendPayload): Promise<void> { export async function sendSmsCode(payload: SmsSendPayload): Promise<void> {
if (!isValidPhone(payload.phone)) { if (!isValidPhone(payload.phone)) {
throw new Error('手机号格式不正确'); throw new Error('手机号格式不正确');
} }
if (isMockMode()) return;
// 后端约束:/auth/sms/send 只接受 Query 参数(body 传参会被当作缺失) // 后端约束:/auth/sms/send 只接受 Query 参数(body 传参会被当作缺失)
await request('/auth/sms/send', { await request('/auth/sms/send', {
method: 'POST', method: 'POST',
@ -99,16 +104,6 @@ export async function loginByPassword(payload: PasswordLoginPayload): Promise<Au
if (!isValidPhone(payload.phone)) { if (!isValidPhone(payload.phone)) {
throw new Error('手机号格式不正确'); throw new Error('手机号格式不正确');
} }
if (isMockMode()) {
const mock = mockAuthTokens(`pwd_${payload.phone}`);
return {
...mock,
userId: 0,
phone: payload.phone,
nickname: 'Mock 用户',
role: 'STUDENT',
};
}
const raw = await request<{ const raw = await request<{
userId: number; userId: number;
phone: string; phone: string;
@ -135,15 +130,6 @@ export async function loginByPassword(payload: PasswordLoginPayload): Promise<Au
}; };
} }
/** mock 形态下返回的双 Token(开发期不触网) */
function mockAuthTokens(nonce: string): AuthTokens {
return {
accessToken: `mock_access_${nonce}`,
refreshToken: `mock_refresh_${nonce}`,
expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000,
};
}
export interface SmsLoginPayload { export interface SmsLoginPayload {
phone: string; phone: string;
code: string; code: string;
@ -163,17 +149,6 @@ export async function loginBySms(payload: SmsLoginPayload): Promise<AuthLoginDat
if (!isValidPhone(payload.phone)) { if (!isValidPhone(payload.phone)) {
throw new Error('手机号格式不正确'); throw new Error('手机号格式不正确');
} }
if (isMockMode()) {
const mock = mockAuthTokens(`sms_${payload.phone}`);
return {
...mock,
userId: 0,
phone: payload.phone,
nickname: 'Mock 用户',
role: 'STUDENT',
identitySelectionRequired: false,
};
}
const raw = await request<{ const raw = await request<{
userId: number; userId: number;
phone: string; phone: string;
@ -227,16 +202,6 @@ export interface CurrentUser {
/** 拉取当前用户与角色(§4 步骤3):角色以后端为准并映射 */ /** 拉取当前用户与角色(§4 步骤3):角色以后端为准并映射 */
export async function fetchCurrentUser(): Promise<CurrentUser> { export async function fetchCurrentUser(): Promise<CurrentUser> {
if (isMockMode()) {
return {
id: 'mock-user',
role: 'candidate',
phone: '',
nickname: 'Mock 用户',
verified: true,
active: true,
};
}
const raw = await request<{ const raw = await request<{
id: number; id: number;
role: BackendRole; role: BackendRole;
@ -259,7 +224,6 @@ export async function fetchCurrentUser(): Promise<CurrentUser> {
/** 退出登录(§4 步骤5):前端清会话由 AuthContext 负责,这里只通知后端 */ /** 退出登录(§4 步骤5):前端清会话由 AuthContext 负责,这里只通知后端 */
export async function requestLogout(): Promise<void> { export async function requestLogout(): Promise<void> {
if (isMockMode()) return;
await request('/auth/logout', { method: 'POST' }); await request('/auth/logout', { method: 'POST' });
} }
@ -284,16 +248,6 @@ export async function registerCompany(payload: CompanyRegisterPayload): Promise<
if (!isValidPhone(payload.phone)) { if (!isValidPhone(payload.phone)) {
throw new Error('手机号格式不正确'); throw new Error('手机号格式不正确');
} }
if (isMockMode()) {
const mock = mockAuthTokens(`company_${payload.phone}`);
return {
...mock,
userId: 0,
phone: payload.phone,
nickname: '企业用户',
role: 'COMPANY',
};
}
const raw = await request<{ const raw = await request<{
userId: number; userId: number;
companyId?: number; companyId?: number;
@ -320,7 +274,6 @@ export interface RefreshTokenPayload {
/** 用 Refresh Token 换取新凭证(旧 Refresh 立即失效) */ /** 用 Refresh Token 换取新凭证(旧 Refresh 立即失效) */
export async function refreshAuthToken(payload: RefreshTokenPayload): Promise<AuthTokens> { export async function refreshAuthToken(payload: RefreshTokenPayload): Promise<AuthTokens> {
if (isMockMode()) return mockAuthTokens('refreshed');
const raw = await request<{ const raw = await request<{
accessToken: string; accessToken: string;
refreshToken: string; refreshToken: string;
@ -362,17 +315,6 @@ export interface IdentitySelectionResult extends AuthLoginData {
* 首次成功撤销全部旧会话并返回新凭证;同身份重复请求只返回状态,不重复颁发凭证。 * 首次成功撤销全部旧会话并返回新凭证;同身份重复请求只返回状态,不重复颁发凭证。
*/ */
export async function selectIdentity(payload: IdentitySelectionPayload): Promise<IdentitySelectionResult> { export async function selectIdentity(payload: IdentitySelectionPayload): Promise<IdentitySelectionResult> {
if (isMockMode()) {
const mock = mockAuthTokens('identity');
return {
...mock,
userId: 0,
phone: '',
nickname: 'Mock 用户',
role: payload.identity,
identitySelectionRequired: false,
};
}
const raw = await request<{ const raw = await request<{
userId: number; userId: number;
role: BackendRole; role: BackendRole;

Loading…
Cancel
Save