Skip to content

Commit f378f34

Browse files
pedrohsbarbosa99Pedro Barbosa
andauthored
feat: add default routers autentication (#35)
* feat: add default routers autentication * feat: add documentation for router authentication --------- Co-authored-by: Pedro Barbosa <[email protected]>
1 parent f988c19 commit f378f34

File tree

6 files changed

+339
-23
lines changed

6 files changed

+339
-23
lines changed

docs/customizing_token_claims.md

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
21
If you wish to customize the claims contained in web tokens which are
32
generated by the `NinjaJWTDefaultController` and `NinjaJWTSlidingController`
43
views, create a subclass for the desired controller as well as a subclass for
54
its corresponding serializer. Here\'s an example :
65

76
!!! info
8-
if you are interested in Asynchronous version of the class, use `AsyncNinjaJWTDefaultController` and `AsyncNinjaJWTSlidingController`.
9-
Also note, it's only available for Django versions that supports asynchronous actions.
7+
if you are interested in Asynchronous version of the class, use `AsyncNinjaJWTDefaultController` and `AsyncNinjaJWTSlidingController`.
8+
Also note, it's only available for Django versions that supports asynchronous actions.
109

1110
```python
1211
from ninja_jwt.schema import TokenObtainPairInputSchema
@@ -18,8 +17,8 @@ from ninja import Schema
1817
class UserSchema(Schema):
1918
first_name: str
2019
email: str
21-
22-
20+
21+
2322
class MyTokenObtainPairOutSchema(Schema):
2423
refresh: str
2524
access: str
@@ -40,34 +39,34 @@ class MyTokenObtainPairController(TokenObtainPairController):
4039
)
4140
def obtain_token(self, user_token: MyTokenObtainPairSchema):
4241
return user_token.output_schema()
43-
42+
4443
```
4544

4645
As with the standard controller, you\'ll also need to include register the controller as shown in `getting_started`
4746

4847
#### Use Django Ninja Router
48+
4949
If you interested in using functions rather than classes, then you are also covered.
5050
Here is an example
5151

5252
```python
53-
from ninja import router
54-
55-
router = router('/token')
56-
57-
@router.post(
58-
"/pair", response=MyTokenObtainPairOutSchema, url_name="token_obtain_pair"
59-
)
60-
def obtain_token(self, user_token: MyTokenObtainPairSchema):
61-
return user_token.output_schema()
53+
from ninja_jwt.routers.blacklist import blacklist_router
54+
from ninja_jwt.routers.obtain import obtain_pair_router, sliding_router
55+
from ninja_jwt.routers.verify import verify_router
6256
```
6357

6458
Register the `router` to the django-ninja `api` like so:
59+
6560
```python
6661
from ninja import NinjaAPI
6762

6863
api = NinjaAPI()
69-
api.add_router('', tags=['Auth'], router=router)
64+
api.add_router('/token', tags=['Auth'], router=obtain_pair_router)
65+
...
7066
```
67+
68+
If you are interested in customize the token claims, you can do so by creating a subclass of `TokenObtainPairInputSchema` and `TokenObtainPairController`. See [Controller Schema Swapping](#controller-schema-swapping)
69+
7170
Also, its important to note that `NinjaExtra` registers a handler for `APIException` class which is not available in `NinjaAPI` instance.
7271
To fix that, you need the extra code below:
7372

@@ -95,8 +94,6 @@ def api_exception_handler(request, exc):
9594
api.exception_handler(exceptions.APIException)(api_exception_handler)
9695
```
9796

98-
99-
10097
### Controller Schema Swapping
10198

10299
You can now swap controller schema in `NINJA_JWT` settings without having to inherit or override Ninja JWT controller function.
@@ -128,7 +125,7 @@ class MyTokenObtainPairInputSchema(TokenObtainInputSchemaBase):
128125
@classmethod
129126
def get_response_schema(cls) -> Type[Schema]:
130127
return MyTokenObtainPairOutSchema
131-
128+
132129
@classmethod
133130
def get_token(cls, user) -> Dict:
134131
values = {}
@@ -139,7 +136,7 @@ class MyTokenObtainPairInputSchema(TokenObtainInputSchemaBase):
139136
return values
140137
```
141138

142-
In the `MyTokenObtainPairInputSchema` we override `get_token` to define our token and some data needed for our output schema.
139+
In the `MyTokenObtainPairInputSchema` we override `get_token` to define our token and some data needed for our output schema.
143140
We also override `get_response_schema` to define our output schema `MyTokenObtainPairOutSchema`.
144141

145142
Next, we apply the `MyTokenObtainPairInputSchema` schema to controller. This is simply done in `NINJA_JWT` settings.
@@ -151,11 +148,10 @@ NINJA_JWT = {
151148
'TOKEN_OBTAIN_PAIR_INPUT_SCHEMA': 'project.schema.MyTokenObtainPairInputSchema',
152149
}
153150
```
151+
154152
Other swappable schemas can be found in [settings](../settings)
155153

156154
![token_customization_git](./img/token_customize.gif)
157155

158156
!!! Note
159-
`Controller Schema Swapping` is only available from **v5.2.4**
160-
161-
157+
`Controller Schema Swapping` is only available from **v5.2.4**

ninja_jwt/routers/__init__.py

Whitespace-only changes.

ninja_jwt/routers/blacklist.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from ninja import Schema
2+
from ninja.router import Router
3+
4+
from ninja_jwt.schema_control import SchemaControl
5+
from ninja_jwt.settings import api_settings
6+
7+
blacklist_router = Router()
8+
9+
schema = SchemaControl(api_settings)
10+
11+
12+
@blacklist_router.post(
13+
"/blacklist",
14+
response={200: Schema},
15+
url_name="token_blacklist",
16+
auth=None,
17+
)
18+
def blacklist_token(request, refresh: schema.blacklist_schema):
19+
return refresh.to_response_schema()

ninja_jwt/routers/obtain.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from ninja.router import Router
2+
3+
from ninja_jwt.schema_control import SchemaControl
4+
from ninja_jwt.settings import api_settings
5+
6+
schema = SchemaControl(api_settings)
7+
8+
obtain_pair_router = Router()
9+
sliding_router = Router()
10+
11+
12+
@obtain_pair_router.post(
13+
"/pair",
14+
response=schema.obtain_pair_schema.get_response_schema(),
15+
url_name="token_obtain_pair",
16+
auth=None,
17+
)
18+
def obtain_token(request, user_token: schema.obtain_pair_schema):
19+
user_token.check_user_authentication_rule()
20+
return user_token.output_schema()
21+
22+
23+
@obtain_pair_router.post(
24+
"/refresh",
25+
response=schema.obtain_pair_refresh_schema.get_response_schema(),
26+
url_name="token_refresh",
27+
auth=None,
28+
)
29+
def refresh_token(request, refresh_token: schema.obtain_pair_refresh_schema):
30+
return refresh_token.to_response_schema()
31+
32+
33+
@sliding_router.post(
34+
"/sliding",
35+
response=schema.obtain_sliding_schema.get_response_schema(),
36+
url_name="token_obtain_sliding",
37+
auth=None,
38+
)
39+
def obtain_token_sliding_token(request, user_token: schema.obtain_sliding_schema):
40+
user_token.check_user_authentication_rule()
41+
return user_token.to_response_schema()
42+
43+
44+
@sliding_router.post(
45+
"/sliding/refresh",
46+
response=schema.obtain_sliding_refresh_schema.get_response_schema(),
47+
url_name="token_refresh_sliding",
48+
auth=None,
49+
)
50+
def refresh_token_sliding(request, refresh_token: schema.obtain_sliding_refresh_schema):
51+
return refresh_token.to_response_schema()

ninja_jwt/routers/verify.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from ninja import Schema
2+
from ninja.router import Router
3+
4+
from ninja_jwt.schema_control import SchemaControl
5+
from ninja_jwt.settings import api_settings
6+
7+
schema = SchemaControl(api_settings)
8+
9+
verify_router = Router()
10+
11+
12+
@verify_router.post(
13+
"/verify",
14+
response={200: Schema},
15+
url_name="token_verify",
16+
auth=None,
17+
)
18+
def verify_token(request, token: schema.verify_schema):
19+
return token.to_response_schema()

0 commit comments

Comments
 (0)