eagleye

buildLoginPayload 函数企业级实现

(一)一、概述

buildLoginPayload 是一个用于构建标准化登录请求载荷的 TypeScript 函数,支持三种输入格式(手机号、邮箱、通用标识符),并通过类型安全校验、自动类型检测及错误规范化,确保登录凭证的健壮性与可维护性。其核心目标是将不同来源的登录凭证(如用户输入的手机号、邮箱或通用标识符)统一转换为服务端可识别的标准格式({ mobile, password }  { email, password }),同时处理无效输入并抛出规范化错误。

(二)二、核心功能与输入规范

1.1. 支持的输入类型

函数通过联合类型 LoginPayloadInput 严格限定输入格式,仅允许以下三种有效格式:

输入类型

字段要求

说明

手机号格式

{ mobile: string; password: string }

直接提供手机号与密码(优先级最高)。

邮箱格式

{ email: string; password: string }

直接提供邮箱与密码(优先级次高)。

通用标识符格式

{ identifier: string; password: string }

提供通用标识符(可能是手机号或邮箱),需通过 detectCredentialType 检测类型。

2.2. 处理优先级规则

函数按以下顺序处理输入,确保无歧义:

graph TD
  A[输入] --> B{是否包含 `mobile` 且非空?}
  B -->|| C[返回 `{ mobile, password }`]
  B -->|| D{是否包含 `email` 且非空?}
  D -->|| E[返回 `{ email, password }`]
  D -->|| F{是否包含 `identifier` 且非空?}
  F -->|| G[检测 `identifier` 类型(手机号/邮箱)]
  G --> H[返回对应类型的标准载荷]
  F -->|| I[抛出无效输入错误]

(三)三、企业级特性详解

1.1. 类型安全约束

通过 TypeScript 联合类型 LoginPayloadInput 强制输入格式,防止无效字段组合:

type LoginPayloadInput =
  | { identifier: string; password: string }
  | { mobile: string; password: string }
  | { email: string; password: string };

效果

• 无效格式(如 { username: 'test', password: 'pwd' })会触发 TypeScript 编译错误。

• 多字段混合(如 { mobile: '138...', email: 'user@c.com', password: 'pwd' })同样会被 TypeScript 拒绝。

2.2. 防御性编程

通过双重校验确保输入有效性:

(1)1)字段存在性检查

使用 in 操作符判断字段是否存在(如 'mobile' in payload),避免访问不存在字段导致的运行时错误。

(2)2)字段非空检查

额外验证字段值非空(如 payload.mobile),防止空字符串通过:

if ('mobile' in payload && payload.mobile) { ... }
// 仅当 `mobile` 存在且非空时处理

3.3. 自动类型检测

对于通用标识符 identifier,通过 detectCredentialType 函数检测其类型(手机号或邮箱),并转换为标准格式:

const type = detectCredentialType(payload.identifier);
return type === 'mobile'
  ? { mobile: payload.identifier, password: payload.password }
  : { email: payload.identifier, password: payload.password };

说明:detectCredentialType 需实现手机号/邮箱的正则校验逻辑(如手机号以 1 开头且长度为 11 位,邮箱包含 @ 符号等)。

4.4. 错误规范化

通过 try-catch 捕获所有可能的错误(包括 detectCredentialType 抛出的错误),并统一错误格式:

throw new Error(`❌登录凭证无效: ${errorMessage}`);

错误场景示例

• 输入无有效字段(如 {}  { password: 'pwd' }→ 抛出 登录凭证无效: 无效的登录凭证格式

• identifier 无法识别(如 'invalid#string'→ 抛出 登录凭证无效: ...(包含 detectCredentialType 的原始错误)。

5.5. 可扩展性

通过扩展 LoginPayloadInput 类型,未来可支持更多登录方式(如用户名):

// 新增用户名类型
type LoginPayloadInput = 
  | { identifier: string; password: string }
  | { mobile: string; password: string }
  | { email: string; password: string }
  | { username: string; password: string }; // 新增字段

(四)四、使用示例

1.1. 直接手机号格式

buildLoginPayload({
  mobile: '13800138000',
  password: 'P@ssw0rd'
});
// 输出: { mobile: '13800138000', password: 'P@ssw0rd' }

2.2. 直接邮箱格式

buildLoginPayload({
  email: 'user@company.com',
  password: 'P@ssw0rd'
});
// 输出: { email: 'user@company.com', password: 'P@ssw0rd' }

3.3. 通用标识符(手机号)

buildLoginPayload({
  identifier: '13800138000',
  password: 'P@ssw0rd'
});
// 输出: { mobile: '13800138000', password: 'P@ssw0rd' }

4.4. 通用标识符(邮箱)

buildLoginPayload({
  identifier: 'user@company.com',
  password: 'P@ssw0rd'
});
// 输出: { email: 'user@company.com', password: 'P@ssw0rd' }

(五)五、测试用例验证

函数已通过以下测试用例,确保健壮性:

输入类型

输入内容

预期输出/行为

有效手机号

{ mobile: '13800138000', password: 'pwd' }

{ mobile: '13800138000', password: 'pwd' }

有效邮箱

{ email: 'user@c.com', password: 'pwd' }

{ email: 'user@c.com', password: 'pwd' }

有效通用标识符(手机号)

{ identifier: '13800138000', password: 'pwd' }

{ mobile: '13800138000', password: 'pwd' }

有效通用标识符(邮箱)

{ identifier: 'user@c.com', password: 'pwd' }

{ email: 'user@c.com', password: 'pwd' }

空手机号

{ mobile: '', password: 'pwd' }

抛出 登录凭证无效: 无效的登录凭证格式

空标识符

{ identifier: '', password: 'pwd' }

抛出 登录凭证无效: 无效的登录凭证格式

无效输入(无字段)

{}

抛出 登录凭证无效: 无效的登录凭证格式

无效输入(仅密码)

{ password: 'pwd' }

抛出 登录凭证无效: 无效的登录凭证格式

(六)六、总结

buildLoginPayload 函数通过 类型安全约束防御性编程自动类型检测 错误规范化,为企业级应用提供了健壮的登录凭证处理能力。其核心优势体现在:

• 类型安全:通过 TypeScript 联合类型避免无效输入,减少运行时错误。

• 灵活兼容:支持三种输入格式(手机号、邮箱、通用标识符),适配多端登录场景。

• 错误友好:统一错误格式,快速定位问题根源。

• 可扩展:支持未来新增登录方式(如用户名),降低维护成本。

此函数适用于需要处理多源登录凭证的企业级前端应用,确保登录流程的稳定性与安全性。

posted on 2025-06-24 17:50  GoGrid  阅读(9)  评论(0)    收藏  举报

导航