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

Loopback 4 JWT认证报错:userCredentials不是函数

LoopBack 4 JWT认证注册报错:TypeError: this.userRepository.userCredentials is not a function

问题概述

  • 技术栈:TypeScript + LoopBack 4 + @loopback/authentication-jwt
  • 操作流程:整合多篇教程开发JWT认证,创建空User模型生成数据表,复制官方示例控制器并修正导入
  • 触发场景:调用/signup接口注册用户时返回500错误
  • 具体报错:
    TypeError: this.userRepository.userCredentials is not a function
    
    错误位置:控制器第156行
  • 排查信息:UserRepository中userCredentials为HasOneRepositoryFactory类型(接口定义为可调用函数),但调用仍报错;已关联Github Issue #6964,项目可通过docker compose启动复现

解决方案

1. 检查UserRepository的关联配置

确保UserRepository中正确初始化HasOne关联的仓库工厂:

export class UserRepository extends DefaultCrudRepository<
  User,
  typeof User.prototype.id,
  UserRelations
> {
  public readonly userCredentials: HasOneRepositoryFactory<UserCredentials, typeof User.prototype.id>;

  constructor(
    @inject('datasources.db') dataSource: DbDataSource,
    @repository.getter('UserCredentialsRepository')
    userCredentialsRepositoryGetter: Getter<UserCredentialsRepository>,
  ) {
    super(User, dataSource);
    // 初始化HasOne关联工厂
    this.userCredentials = this.createHasOneRepositoryFactoryFor(
      'userCredentials',
      userCredentialsRepositoryGetter,
    );
    // 注册包含解析器(可选,用于关联查询)
    this.registerInclusionResolver('userCredentials', this.userCredentials.inclusionResolver);
  }
}

2. 修正控制器中关联仓库的调用方式

HasOneRepositoryFactory是工厂函数,需要传入用户ID来获取对应的UserCredentialsRepository实例,再执行创建操作:

// 错误写法(直接调用工厂函数但未传参)
// await this.userRepository.userCredentials({ password: hashedPassword });

// 正确写法
// 1. 先通过用户ID获取关联仓库实例
const userCredentialsRepo = this.userRepository.userCredentials(newUser.id);
// 2. 调用关联仓库的create方法创建凭证
await userCredentialsRepo.create({ password: hashedPassword });

3. 验证模型关联配置

确保User和UserCredentials模型的双向关联定义正确:

  • User模型:
    @model()
    export class User extends Entity {
      @property({
        type: 'number',
        id: true,
        generated: true,
      })
      id?: number;
    
      // 定义HasOne关联
      @hasOne(() => UserCredentials)
      userCredentials?: UserCredentials;
    
      constructor(data?: Partial<User>) {
        super(data);
      }
    }
    
  • UserCredentials模型:
    @model()
    export class UserCredentials extends Entity {
      @property({
        type: 'number',
        id: true,
        generated: true,
      })
      id?: number;
    
      @property({
        type: 'string',
        required: true,
      })
      password: string;
    
      // 定义BelongsTo关联
      @belongsTo(() => User)
      userId: number;
    
      constructor(data?: Partial<UserCredentials>) {
        super(data);
      }
    }
    

补充说明

该问题核心原因是对LoopBack 4中HasOneRepositoryFactory的调用逻辑理解偏差——工厂函数需要先传入关联实体的ID,才能获取到可操作的关联仓库实例,而非直接传入创建参数,此问题与Github Issue #6964相关。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:45:43