iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
1

除了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


上一篇
Day11-Guard(Authentication) in nest.js(上)
下一篇
Day13- Interceptor in nest.js
系列文
讀官網文件邊走邊學nest.js31

1 則留言

0
q2234037172
iT邦新手 5 級 ‧ 2019-01-21 14:38:39

您好:

Logger.log('---允許的Roles有---');

請問 Logger 是如何實現的
有完整demo 示例嗎?
謝謝~

我要留言

立即登入留言