#NestJS + Passport-JWT + Supabase Problem

13 messages · Page 1 of 1 (latest)

fiery kraken
#

Hello,

I'm currently facing an issue while working with NestJS, Passport-JWT, and Supabase. Here's how my workflow unfolds: I initiate requests from my frontend, including an access token obtained from Supabase, which is included in the authorization header with the format "Bearer: ...".

This is my strategy:

@Injectable()
export class SupabaseStrategy extends PassportStrategy(Strategy) {
  constructor(configService: ConfigService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: configService.get('SUPABASE_JWT_SECRET'),
    });
  }

  async validate() {
    Promise.resolve(true);
  }

  authenticate(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, options?: any): boolean {
    return true
  }
}

This is my guard:

@Injectable()
export class SupabaseGuard extends AuthGuard('jwt') {}

And this my module, which is imported into the app.module.ts:

@Module({
    imports: [
        PassportModule,
        JwtModule.registerAsync({
            imports: [ConfigModule],
            useFactory: async (configService: ConfigService) => {
                return {
                    secret: configService.get<string>('SUPABASE_JWT_SECRET')
                }
            },
            inject: [ConfigService]
        }),
    ],
    providers: [SupabaseService, SupabaseStrategy],
    exports: [SupabaseService, JwtModule, PassportModule]
})
export class SupabaseModule { }

If I currently send requests to an endpoint that utilizes the @UseGuards(SupabaseGuard) decorator, the requests appear to hang in a "pending" state indefinitely. I've followed the documentation on nestjs.com, but I'm unsure where I may have gone wrong.
Could someone please provide some assistance or guidance to help resolve this issue?

lapis viper
#

Can you show the route handler as well?

fiery kraken
#

@lapis viper

    @Post()
    @UseGuards(SupabaseGuard)
    async postConfig(@Body() config: ConfigDto, @Res() res: Response) {
        const { name, theme } = config;

        const { password, ...rest } = await this.databaseService.customer.create({
            data: {
                name,
                ...theme,
                customerId: uuidV4(),
                password: 'test',
                trustedEmail: 'test@test.de'
            }
        });

        return res.status(201).json(rest);
    }
lapis viper
#

Hmmm, so you do actually send a response. My first thought was that you had @Res(), but no res.send/`res.json|

fiery kraken
#

It's strange. If I remove the "authenticate" function in the strategy, the response becomes 401 Unautorized.

lapis viper
#

validate doesn't return anything, so it's seen as an undefined response which would make sense to get a 401 back for with how passport works.

#

I'll need to look into what is doing with authenticate

fiery kraken
#

But even if I return something in the validate function, I still receive a 401

lapis viper
#

A straight 401 could be an invalid token. One moment

#

Take your SupabaseGuard and add this:

handleRequest(...args: Parameters<InstanceType<ReturnType<typeof AuthGuard>>['handleRequest']>) {
  console.log(args);
  return super.handleRequest(...args);
}
fiery kraken
#

That helped me figure it out. The token was expired and therefore I got a 401. Thank you very much @lapis viper

ivory quest
#

has anyone figured this out? im having trouble with Unknown authentication strategy "jwt" when i use the guard

lapis viper
#

That usually means you didn't add the strategy to a providers array, or your strategy is request scoped