admin管理员组文章数量:1323323
I've created some custom parameter decorators for my routes, but I do not find any useful documentation on how to create a decorator for the route itself. There is some description how to bundle existing method decorators together which does not help me.
What I'm trying to achieve is some simple scope validation. The scopes are already set up in the request context. What I currently have, only based on TypeScript decorators, but is actually going nowhere:
controller.ts
@RequiredScope(AuthScope.OWNER)
@Get('/some-route')
async get() {
...
}
required-scopes.ts
export function RequiredScope(...scopes: string[]) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
console.log(`Validation of scopes '${scopes.join(',')}' for input '${RequestContext.getScopes().join(',')}'`)
if (!scopes.map(s => RequestContext.hasOneOfTheScopes(s)).find(valid => !valid)) {
throw new HttpException(`Missing at least one scope of '${scopes.join(',')}'`, HttpStatus.FORBIDDEN)
}
}
}
Problem here is that my request context is not even available because my middleware which does set up my context did not kick in yet. The request is failing immediately.
Can somebody point me into the right direction?
I've created some custom parameter decorators for my routes, but I do not find any useful documentation on how to create a decorator for the route itself. There is some description how to bundle existing method decorators together which does not help me.
What I'm trying to achieve is some simple scope validation. The scopes are already set up in the request context. What I currently have, only based on TypeScript decorators, but is actually going nowhere:
controller.ts
@RequiredScope(AuthScope.OWNER)
@Get('/some-route')
async get() {
...
}
required-scopes.ts
export function RequiredScope(...scopes: string[]) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
console.log(`Validation of scopes '${scopes.join(',')}' for input '${RequestContext.getScopes().join(',')}'`)
if (!scopes.map(s => RequestContext.hasOneOfTheScopes(s)).find(valid => !valid)) {
throw new HttpException(`Missing at least one scope of '${scopes.join(',')}'`, HttpStatus.FORBIDDEN)
}
}
}
Problem here is that my request context is not even available because my middleware which does set up my context did not kick in yet. The request is failing immediately.
Can somebody point me into the right direction?
Share edited Feb 27, 2021 at 23:04 tpschmidt asked Jul 31, 2020 at 12:54 tpschmidttpschmidt 2,7272 gold badges24 silver badges34 bronze badges 2- 1 Have you tried to use a guard instead of making a decorator? docs.nestjs./guards – Khaled Mohamed Commented Jul 31, 2020 at 13:05
- Thank you very much for this advice. It worked out quite nicely. Also, it fits a lot better for this use case. – tpschmidt Commented Jul 31, 2020 at 15:34
1 Answer
Reset to default 5As kindly proposed by Khaled Mohamed (thank you!), solving this with guards was quite simple and a better approach.
Creating a decorator with the required scopes as a param in scopes.decorator.ts:
export const Scopes = (...scopes: string[]) => SetMetadata('scopes', scopes)
Setting up a guard which checks the provided meta scopes
and does check if the requirement is fulfilled in scopes.guard.ts:
@Injectable()
export class ScopesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const scopes = this.reflector.get<string[]>('scopes', context.getHandler())
if (!scopes || scopes.length === 0) return true
if (!scopes.map(s => RequestContext.hasOneOfTheScopes(s)).find(valid => !valid)) {
throw new HttpException(`Missing at least one scope of '${scopes.join(',')}'`, HttpStatus.FORBIDDEN)
}
return true
}
}
Activating the guard globally in app.module.ts:
@Module({
imports: [...],
controllers: [...],
providers: [
{
provide: APP_GUARD,
useClass: ScopesGuard,
}
],
})
Using the decorator at the route in controller.ts:
@Scopes(AuthScope.OWNER)
@Get('/some-route')
async get() {
...
}
本文标签: javascriptCustom Route Decorators for NestJSStack Overflow
版权声明:本文标题:javascript - Custom Route Decorators for NestJS - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742140976a2422577.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论