#How can i inject microservice into guard

19 messages · Page 1 of 1 (latest)

turbid shore
#

I have folder structure like this. But i can't inject token service/token module to guard.

This is how code works;

  • I send post request to user endpoint (for create user) ✅
  • I am checking additional info at guard. ✅
  • If token is not provided,return 401 ✅
  • if token provided and not valid return 401 ❌

Information
Normally its working if i send message from controllers, services. But it doesn't work if message coming from guard

here is code:
Create-guard.ts

@Injectable()
export class AuthRequired implements NestMiddleware {
  constructor(
    @Inject(ACCOUNT_SERVICE_NAME) private readonly accountQueue: ClientProxy,
  ) {}

  async use(req: Request, res: Response, next: (error?: NextFunction) => void) {
    const { isRoot } = req.body;
    const token = this.extractToken(req);
    if (isRoot === 'false') {
      if (!token) {
        return res.status(HttpStatus.UNAUTHORIZED).send({
          message: 'You must be logged in to perform this action',
        });
      }

      const isValid = this.accountQueue.send({ cmd: 'isTokenValid' }, token);
      return isValid;
    }
    next();
  }

  private extractToken(req: Request) {
    const authHeader = req.headers.authorization;
    if (!authHeader) {
      return null;
    }
    const token = authHeader.split(' ')[1];
    return token;
  }
}

Account.module.ts

@Module({
  imports: [
    ClientsModule.register([
      {
        name: ACCOUNT_SERVICE_NAME,
        transport: Transport.RMQ,
        options: {
          urls: BROKERS,
          queue: ACCOUNT_QUEUE_NAME,
          queueOptions: {
            durable: false,
          },
        },
      },
    ]),
    SequelizeModule.forFeature([Account]),
  ],
  controllers: [AccountController],
  providers: [AccountService],
})

Token.controller.ts

  @MessagePattern({ cmd: 'isTokenValid' })
  async isTokenValidHandler(token: string) {
    console.log('DEBUGGGG');
    return this.tokenService.isTokenValid(token);
  }
turbid shore
#

it stucks infinite waiting

turbid shore
#

i forgot to return response. i fixed it with those lines

      const isValid = this.accountQueue.send({ cmd: 'isTokenValid' }, token);
      console.log(isValid);
      return res.status(HttpStatus.UNAUTHORIZED).send({
        message: isValid,
      });

output:
console

Observable {
  source: Observable { _subscribe: [Function (anonymous)] },
  operator: [Function (anonymous)]
}

endpoint

{
    "message": {
        "source": {}
    }
}
turbid shore
turbid shore
#

i can use service file to call function but i want to call through message broker

wary crow
#

The client proxy uses observables to serve and retrieve the data. If you aren't comfortable with rxjs, you can wrap the call in a lastValueFrom() to turn it into a promise

turbid shore
#

my problem was that

#

im sending "{ cmd: 'isTokenValid' }" message

#

i cannot get red arrow

#

but when i send message from another controller, im getting debuggg message

wary crow
#

Looks like the observable is never sent, there must be a subscriber to kick off the observable as send uses cold observables, so you either need to .subscribe or wrap it in the lastValueFrom()

turbid shore
#

which one do you prefer as a core team member

wary crow
#

I like rxjs, it's a useful approach and a powerful tool, but it can also be a decent bit of overhead if you aren't too comfortable with it. Converting to a promise for brevity is fine.

Use what works and it's easy to understand

turbid shore
#

lastvaluefrom more easy

#

btw why do we need to use this

#

why just this.accountQueue.send({ cmd: 'isTokenValid' }, token) didn't return

#

and we need to use ```js

const isValid = await lastValueFrom(
this.accountQueue.send({ cmd: 'isTokenValid' }, token),
);