You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS用户认证登录报错:Cannot read properties of undefined (reading 'username')

问题排查与解决方案

错误原因分析

核心问题

登录接口未启用Local认证守卫,导致req.user未初始化。你的AuthController中login方法的@UseGuards(AuthGuard('local'))被注释,Passport的本地认证策略无法执行,也就不会将验证后的用户对象挂载到req.user上。调用this.authService.login(req.user)时,req.user为undefined,自然无法读取username属性。

次要逻辑问题

  1. AuthService.validateUser存在冗余判断:开头已判断if (!user) return null,后续重复的if (!user)抛出异常逻辑永远不会执行。
  2. UsersService导入的User接口与Schema定义的User类不匹配,可能引发类型校验问题。

解决方案

1. 启用LocalAuthGuard并修正接口路径

取消AuthController中守卫的注释,同时修正冗余的接口路径:

@Controller('auth')
export class AuthController {
    constructor(private authService: AuthService) {}

    @UseGuards(AuthGuard('local')) // 取消注释,启用本地认证守卫
    @Post('login') // 原路径/auth/auth/login重复,改为/login后接口路径为/auth/login
    async login(@Request() req) {
        return this.authService.login(req.user);
    }
}

2. 清理AuthService冗余逻辑

删除validateUser中重复的判断,并优化用户返回结果(剔除敏感密码字段):

async validateUser(username: string, password: string): Promise<any> {
    const user = await this.usersService.getUser({ username });
    if (!user) {
        throw new NotAcceptableException('could not find the user');
    }
    const passwordValid = await bcrypt.compare(password, user.password);
    if (passwordValid) {
        const { password, ...result } = user; // 剔除密码字段
        return result;
    }
    return null;
}

3. 统一UsersService的User类型

将UsersService导入的User替换为Schema定义的类,确保类型一致:

// 替换原导入语句,根据你的实际文件路径调整
import { User, UserDocument } from '../schemas/user.schema'; 

@Injectable()
export class UsersService {
    constructor(@InjectModel(User.name) private readonly userModel: Model<UserDocument>) {}

    // 调整返回类型为UserDocument
    async getUser(query: object ): Promise<UserDocument> {
        return this.userModel.findOne(query);
    }

    // 其他方法保持不变,注意返回类型统一为UserDocument
}

4. 验证前端传参格式

确保前端请求/auth/login时,请求体包含username和password字段(Passport LocalStrategy默认读取这两个字段)。如果前端使用其他字段名(如email),需在LocalStrategy中配置:

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    // 若前端传参为email和password,添加如下配置
    // super({ usernameField: 'email' });
    super(); // 默认使用username和password
  }

  // 其余逻辑不变
}

测试验证

完成修改后重启服务,调用POST /auth/login接口并传入正确的账号密码,应能正常返回access_token,不再出现Cannot read properties of undefined (reading 'username')错误。

内容的提问来源于stack exchange,提问作者Graham Morby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:15:35