I'm writing webAPI using NestJS framework. I was not able to override global scoped guard with the one placed on method or controller level. All of my endpoints will use JWT verification guard except one used for logging into the system. Is it possible to create one guard on root level and only override this global guard with @UseGuard()
decorator on single method level?
I tried to use guard before listen
function call and also use APP_GUARD
provider, but in both cases I'm not able to override this behavior.
Code example: https://codesandbox.io/embed/nest-yymkf
Just to add my 2 cents.
Instead of defining 2 guards (reject
and accept
) as the OP have done, I have defined a custom decorator:
import { SetMetadata } from '@nestjs/common'
export const NoAuth = () => SetMetadata('no-auth', true)
The reject guard (AuthGuard
) uses Reflector
to be able to access the decorator's metadata and decides to activate or not based on it.
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { Observable } from 'rxjs'
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const noAuth = this.reflector.get<boolean>('no-auth', context.getHandler())
if(noAuth) return true
// else your logic here
}
}
I then bind the reject
guard globally in some module:
@Module({
providers: [{
provide: APP_GUARD,
useClass: AuthGuard
}]
})
and proceed to use the decorator where needed:
@NoAuth()
@Get() // anyone can access this
getHello(): string {
return 'Hello Stranger!'
}
@Get('secret') // protected by the global guard
getSecret(): string {
return 'ssshhh!'
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With