#Always process jwt
31 messages · Page 1 of 1 (latest)
You can specify a provider in app.module.ts that looks like this:
{
provide: APP_GUARD,
useClass: AuthGuard // replace this with your own class
}
And you can import APP_GUARD constant from @nestjs/core
import { APP_GUARD } from '@nestjs/core';
This will apply the guard globally
sounds like you want a global guard or middleware
if i understood the problem correctly
I've thinked a bit,
-> a modified jwt guard that doesn't throw error, and populate user context
-> a custom guard, that verify the user context, and throw error if the context is null
You need to come up with a system of access for your application, if the API should be mixed between public and confidential viewing. In other words, access controls are set deeper in the stack. Like possibly at resolver level.
And you need a way to decide. Is this a known or an unknown user and if unknown, what do I allow to be shown.
Yeah, qctually, it's specified at field level with an extension containing the scope of the field
if loggin for example loggin is required
Yeah, so you probably need something that will identify a resolver as "public" or not. Right?
That is a very simple solution.
actually, every resolver is public, only certains methods / fields are private and should be null
Then you need to go even deeper. Field level security is a hard and complex thing to accomplish.
CASL can do this too, but again. Very difficult to pull off well. https://casl.js.org/v6/en/guide/restricting-fields
okay, thank you 😍
perhaps casbin might be able as well
I just noticed Google took me to version 4 of CASL, yet version 6 is the latest version. I've updated the link above.
this (processing JWT's even on routes marked with @Public ) does not seem to be possible when using PassportJS's 'passport-jwt' strategy
Directly, no, but you can call super.canActivate(context) and return true regardless the outcome
Assuming your guard extended AuthGuard('jwt')
@burnt vale thanks.. but then where would i check for the IS_PUBLIC_KEY and use it?
Save the super.canActivate result to a variable.. After the call, check for the metadata, if it exists return true, if it doesn't what return the result
Thanks again, @burnt vale -- thx to you, i'm making progress! Now I've discovered that my async validate function in my JwtStrategy is being called after my resolver is called... could that be a problem with Passport?
Did you await the super call?
no because the canActivate function can't be async..
It can. It can return a Boolean, a Promise<Boolean> or an Observable<Boolean
hmm.. when i mark it as async, i get TS errors...
Property 'canActivate' in type 'JwtAuthGuard' is not assignable to the same property in base type 'IAuthGuard'.
Type '(context: ExecutionContext) => Promise<boolean | Observable<boolean>>' is not assignable to type '(context: ExecutionContext) => boolean | Promise<boolean> | Observable<boolean>'.
Give it an as Promise<Boolean> because the types are too wide otherwise
What does your code look like at the moment?
override async canActivate(context: ExecutionContext) {
const isValid = await super.canActivate(context);
const contextType = context.getType<'http' | 'stripe_webhook'>();
if (contextType === 'stripe_webhook' || contextType === 'http') {
// will be handled by the stripe webhook handler...
return true;
}
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
// we allow public access
return true;
}
return isValid;
}
Hmm, yeah I'd think Typescript should be okay with that.