除了authentication,通常會需要以role來管理頁面權限。
昨天提到Guard中的canActivate會傳入ExecutionContext,透過reflect metadata可以取得處理request的對應controller及方法,進一步我們希望在controller下對應的方法指定權限,如新增使用者需要admin權限,然而問題是AuthGuard要怎麼從controller讀取權限設定值?
nest.js還提供可以被注入@ReflectMetadata decorator,動態取得bind在method上的參數,如下
app.controller.ts
@Controller()
@UseGuards(AuthGuard)
@UseFilters(HttpInterceptor)
export class AppController {
...
@Post()
@ReflectMetadata('roles', ['admin']) //@ReflectMeatadata提供key-value pair功能,之後可以在AuthGuard裡面取的此metadata
@UsePipes(UserDTOValidationPipe)
create(@Body() userDTO: UserDTO){
throw new HttpException('糟糕!您的要求有問題,請洽系統管理員', HttpStatus.BAD_REQUEST);
return `使用者:${userDTO.username}已建立`;
}
...
}
修改auth.guard.ts
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private readonly reflector:Reflector) //注入Reflector,存取相關metadata
canActivate(
context: ExecutionContext, // 可以取得對應controller及request/request資訊
): boolean | Promise<boolean> | Observable<boolean> {
// 驗證邏輯
const req=context.switchToHttp().getRequest(); // 取得request物件
const ctrl=context.getClass(); // 取得Controller name
const handler=context.getHandler(); // 取得處理request對應的方法
// 利用get取得'roles'的值
// 第二個參數是告訴reflector取得哪一個方法的metadata
const roles=this.reflector.get<string[]>('roles', handler);
Logger.log('---允許的Roles有---');
// 使用Logger來測試有沒有取得roles的對應的value
Logger.log(roles);
if(req.hostname ==='localhost'){
return true;
}
return false
}
}
用postman測試並觀察console output
您好:
Logger.log('---允許的Roles有---');
請問 Logger
是如何實現的
有完整demo 示例嗎?
謝謝~