how to inject my services layer into Auth Guard? NestJS - AuthGuards

762 Views Asked by At

I am creating an authentication system via UseGuards, but how can I inject dependencies into my guards? I'd like to do it in a global way, to avoid repeating code and every controller importing the injections.

I am using the mode of dependency inversion and injecting the classes, I am also making the classes only depend on implementations and interface rules...

My AuthServices

export class AuthServices implements IMiddlewareAuth {
  constructor(
    private readonly jwt: IJWTDecrypt,
    private readonly authUserRepo: IAuthUserContract,
  ) {}

  public async intercept(
    req: IMiddlewareAuth.Attrs,
  ): Promise<IMiddlewareAuth.Return> {
    const token = req.headers['Authorization'];

    if (!token) {
      new Fails('Access denied', 403);
    }

    const parts = token.split(' ');
    if (parts.length !== 2) {
      return new Fails('Anauthorized', 401);
    }

    const [scheme, access] = parts;
    if (!/^Bearer$/i.test(scheme)) {
      return new Fails('Anauthorized', 400);
    }

    const id = await this.jwt.decrypt(access);
    if (!id) {
      return new Fails('Anauthorized', 400);
    }

    const user = await this.authUserRepo.findById(id);
    if (!user) {
      return new Fails('Anauthorized', 400);
    }

    return user;
  }
}

my Auth.Guards

@Injectable()
export class AuthorizationGuard implements CanActivate {
  constructor(
    @Inject('AuthServices')
    private authServices: IMiddlewareAuth,
  ) {}

  public async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();

    const user = await this.authServices.intercept(request);
    if (user instanceof Fails) {
      throw new HttpException(
        {
          statusCode: user.statusCode,
          error: user.message,
        },
        user.statusCode,
      );
    }

    request.user = {
      email: user.email,
      id: user.id,
      name: user.name,
    } as ISessionLogin;

    return true;
  }
}

my Auth.Module

@Module({
  imports: [ConfigModule.forRoot(), TypeOrmModule.forFeature([UserEntity])],
  providers: [
    {
      provide: AuthUserRepository,
      useFactory: (dataSource: DataSource) => {
        return new AuthUserRepository(
          dataSource.getMongoRepository(UserEntity),
        );
      },
      inject: [getDataSourceToken()],
    },
    {
      provide: JsonWebToken,
      useFactory: () => {
        return new JsonWebToken();
      },
    },
    {
      provide: AuthServices,
      useFactory: (
        jwt: JsonWebToken,
        authUserRepository: AuthUserRepository,
      ) => {
        return new AuthServices(jwt, authUserRepository);
      },
      inject: [JsonWebToken, AuthUserRepository],
    },
  ],
  exports: [AuthServices],
})
export class AuthModule {}

Error

enter image description here

1

There are 1 best solutions below

4
On

Use @Inject(AuthService) instead of @Inject('AuthService'). The important distinction is that 'AuthService' is a string token that matches AuthService.name and AuthService is a class reference. Also, make sure the CreateUsersModule has AuthModule in its imports array