NestJS手机号登录问题:无法获取phoneNumber字段的排查求助
NestJS手机号登录无法获取phoneNumber字段问题
问题现象
- 当请求携带
email字段时,登录流程正常执行 - 当请求携带
phoneNumber字段时,登录失败,无法完成认证
排查尝试
在LocalStrategy的构造函数中添加字段映射配置,但未生效:
super({ usernameField: "email", phoneField: "phoneNumber", });
添加console.log打印参数后,仅password能获取到有效值,email和phoneNumber均为undefined。
相关代码
@Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private authService: AuthService) { super({ usernameField: "email", phoneField: "phoneNumber", }); } async validate( email: string, password: string, phoneNumber: string, ): Promise<any> { console.log(` mail ${email}`) console.log(` pass ${password}`) console.log(` phone ${phoneNumber}`) const user = await this.authService.validateUser( email, password, phoneNumber, ); if (!user) { throw new UnauthorizedException('Неверный логин или пароль'); } return user; } }
解决方案
1. 修正Strategy配置逻辑
Passport的LocalStrategy默认只支持usernameField和passwordField两个配置项,自定义的phoneField不会被识别。要获取额外字段,需开启passReqToCallback: true,让validate方法接收完整请求对象,直接从请求体提取字段:
@Injectable() export class LocalStrategy extends PassportStrategy(Strategy) { constructor(private authService: AuthService) { super({ usernameField: "email", passReqToCallback: true, // 关键配置:传递请求对象到validate }); } async validate( req: Request, // 第一个参数为请求对象 email: string, password: string, ): Promise<any> { // 从请求体中直接获取phoneNumber const phoneNumber = req.body.phoneNumber; console.log(` mail ${email}`) console.log(` pass ${password}`) console.log(` phone ${phoneNumber}`) const user = await this.authService.validateUser( email, password, phoneNumber, ); if (!user) { throw new UnauthorizedException('Неверный логин или пароль'); } return user; } }
2. 兼容邮箱/手机号双登录(可选)
如果需要同时支持两种登录方式,可在validate中判断字段存在性,调用对应验证逻辑:
async validate(req: Request, email: string, password: string): Promise<any> { const { phoneNumber } = req.body; let user; if (phoneNumber) { user = await this.authService.validateUserByPhone(phoneNumber, password); } else if (email) { user = await this.authService.validateUserByEmail(email, password); } else { throw new UnauthorizedException('请提供邮箱或手机号'); } if (!user) { throw new UnauthorizedException('Неверный логин или пароль'); } return user; }
3. 确认请求体解析配置
确保NestJS应用已启用请求体解析中间件(NestJS默认配置express.json()和express.urlencoded()),否则无法正确读取req.body中的字段。
内容的提问来源于stack exchange,提问作者Максим Дмитриевич
相关产品推荐
相关产品推荐

