@@ -43,3 +43,62 @@ class JWTGuard(BaseGuard):
4343``` 
4444
4545Attach the guard with ` @UseGuards(JWTGuard) `  on controllers or routes to secure them.
46+ 
47+ ## Controller vs. Route Guards  
48+ 
49+ You can attach guards at the controller level so they apply to every route in the
50+ controller. Individual routes can also specify their own guards.
51+ 
52+ ``` python 
53+ @Controller (' /admin' 
54+ @UseGuards (AdminGuard)
55+ class  AdminController :
56+     @Get (' /dashboard' 
57+     def  dashboard (self 
58+         return  {' ok' True }
59+ 
60+     @Post (' /login' 
61+     @UseGuards (PublicOnlyGuard)
62+     def  login (self 
63+         return  {' logged_in' True }
64+ ``` 
65+ 
66+ In this example ` AdminGuard `  protects all routes while ` PublicOnlyGuard `  is applied
67+ only to the ` login `  route.
68+ 
69+ ## Combining Multiple Guards  
70+ 
71+ ` UseGuards `  accepts any number of guard classes. All specified guards must return
72+ ` True `  in order for the request to proceed.
73+ 
74+ ``` python 
75+ class  TokenGuard (BaseGuard ):
76+     def  can_activate (self request : Request) -> bool :
77+         return  request.headers.get(' x-token' ==  ' secret' 
78+ 
79+ class  RoleGuard (BaseGuard ):
80+     def  can_activate (self request : Request) -> bool :
81+         return  request.state.user_role ==  ' admin' 
82+ 
83+ @Controller (' /secure' 
84+ class  SecureController :
85+     @Get (' /' 
86+     @UseGuards (TokenGuard, RoleGuard)
87+     def  root (self 
88+         return  {' ok' True }
89+ ``` 
90+ 
91+ ## Asynchronous Guards  
92+ 
93+ Guards can perform asynchronous checks by returning an awaitable from
94+ ` can_activate ` .
95+ 
96+ ``` python 
97+ class  AsyncGuard (BaseGuard ):
98+     async  def  can_activate (self request : Request) -> bool :
99+         user =  await  get_user_from_db(request.headers[' X-User' 
100+         return  user is  not  None 
101+ ``` 
102+ 
103+ PyNest awaits the result automatically.
104+ 
0 commit comments