Skip to content

Commit 8e54499

Browse files
author
IndominusByte
committed
complete all docs
1 parent 7185807 commit 8e54499

25 files changed

+346
-15
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@
22
FastAPI JWT Auth
33
</h1>
44

5-
[![Build Status](https://travis-ci.org/IndominusByte/fastapi-jwt-auth.svg?branch=master)](https://travis-ci.org/IndominusByte/fastapi-jwt-auth)
5+
![Tests](https://github.com/IndominusByte/fastapi-jwt-auth/workflows/Tests/badge.svg)
66
[![Coverage Status](https://coveralls.io/repos/github/IndominusByte/fastapi-jwt-auth/badge.svg?branch=master)](https://coveralls.io/github/IndominusByte/fastapi-jwt-auth?branch=master)
77
[![PyPI version](https://badge.fury.io/py/fastapi-jwt-auth.svg)](https://badge.fury.io/py/fastapi-jwt-auth)
88
[![Downloads](https://static.pepy.tech/personalized-badge/fastapi-jwt-auth?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/fastapi-jwt-auth)
99

1010
---
1111

12+
**Documentation**: <a href="https://indominusbyte.github.io/fastapi-jwt-auth" target="_blank">https://indominusbyte.github.io/fastapi-jwt-auth</a>
13+
14+
**Source Code**: <a href="https://github.com/IndominusByte/fastapi-jwt-auth" target="_blank">https://github.com/IndominusByte/fastapi-jwt-auth</a>
15+
16+
---
17+
1218
## Features
13-
FastAPI extension that provides JWT Auth support (secure, easy to use and lightweight), if you were familiar with flask-jwt-extended this extension suitable for you because this extension inspired by flask-jwt-extended 😀
19+
FastAPI extension that provides JWT Auth support (secure, easy to use and lightweight), if you were familiar with flask-jwt-extended this extension suitable for you, cause this extension inspired by flask-jwt-extended 😀
1420

1521
- Access tokens and refresh tokens
1622
- Freshness Tokens
1723
- Revoking Tokens
1824
- Support for adding custom claims to JSON Web Tokens
19-
- Support RSA encryption
2025
- Storing tokens in cookies and CSRF protection
2126

2227
## Installation
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
You may want to store additional information in the access token or refresh token and you could later access in the protected views. This can be done easily by parsing additional information *(dictionary python)* to parameter **user_claims** in function **create_access_token()** or **create_refresh_token()**, and the data can be accessed later in a protected endpoint with the **get_raw_jwt()** function.
2+
3+
Storing data in the tokens can be good for performance. If you store data in the tokens, you won't need to look it up from disk next time you need it in a protected endpoint. However, you should take care of what data you put in the tokens. Any data in the tokens can be trivially viewed by anyone who can read the tokens.
4+
5+
**Note**: *Do not store sensitive information in the tokens!*
6+
7+
```python hl_lines="34-35 44"
8+
{!../examples/additional_claims.py!}
9+
```

docs/advanced-usage/bigger-app.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Because *fastapi-jwt-auth* configure your setting via class state that applies across all instances of the class. You need to make sure to call **load_config**(callback) above from your endpoint. Thanks to `FastAPI` when you make endpoint from `APIRouter` it will actually work as if everything was the same single app.
2+
3+
So you only need to define **load_config**(callback) where `Fastapi` instance created or you can import it where you included all the router.
4+
5+
## An example file structure
6+
7+
Let's say you have a file structure like this:
8+
9+
```
10+
.
11+
├── multiple_files
12+
│ ├── __init__.py
13+
│ ├── app.py
14+
│ └── routers
15+
│ ├── __init__.py
16+
│ ├── items.py
17+
│ └── users.py
18+
```
19+
20+
Here an example of `app.py`
21+
22+
```python
23+
{!../examples/multiple_files/app.py!}
24+
```
25+
26+
Here an example of `users.py`
27+
28+
```python
29+
{!../examples/multiple_files/routers/users.py!}
30+
```
31+
32+
Here an example of `items.py`
33+
34+
```python
35+
{!../examples/multiple_files/routers/items.py!}
36+
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
You can specify which algorithm you would like to use to sign the JWT by using the **algorithm** parameter in **create_access_token()** or **create_refresh_token()**. Also you need to specify which algorithms you would like to permit when validating in protected endpoint by settings `authjwt_decode_algorithms` which take a *sequence*. If the JWT doesn't have algorithm in `authjwt_decode_algorithms` the token will be rejected.
2+
3+
```python hl_lines="16 35-36"
4+
{!../examples/dynamic_algorithm.py!}
5+
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
You can also change the expires time for a token via parameter **expires_time** in the **create_access_token()** or **create_refresh_token()** function. This takes a *datetime.timedelta*, *integer*, or even *boolean* and overrides the `authjwt_access_token_expires` and `authjwt_refresh_token_expires` settings. This can be useful if you have different use cases for different tokens.
2+
3+
```python
4+
@app.post('/create-dynamic-token')
5+
def create_dynamic_token(Authorize: AuthJWT = Depends()):
6+
expires = datetime.timedelta(days=1)
7+
token = Authorize.create_access_token(subject="test",expires_time=expires)
8+
return {"token": token}
9+
```
10+
11+
You can even disable expiration by setting **expires_time** to *False*:
12+
13+
```python
14+
@app.post('/create-token-disable')
15+
def create_dynamic_token(Authorize: AuthJWT = Depends()):
16+
token = Authorize.create_access_token(subject="test",expires_time=False)
17+
return {"token": token}
18+
```

docs/advanced-usage/generate-docs.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
It feels incomplete if there is no documentation because *fastapi-jwt-auth* that uses starlette request and response directly to get headers or cookies, you must manually generate the documentation. Thanks to `FastAPI` you can generate doc easily via `Extending OpenAPI`.
2+
3+
Here is an example to generate the doc:
4+
5+
```python hl_lines="37 57-65 69 71-78"
6+
{!../examples/generate_doc.py!}
7+
```

docs/api-doc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ In here you will find the API for everything exposed in this extension.
1010

1111
**token_in_denylist_loader**(callback)
1212
: *This decorator sets the callback function that will be called when
13-
a protected endpoint is accessed and will check if the JWT has been
13+
a protected endpoint is accessed and will check if the JWT has
1414
been revoked. By default, this callback is not used.*
1515

1616
**Hint**: *The callback must be a function that takes `one` argument, which is the decoded JWT (python dictionary),

docs/configuration/cookies.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ These are only applicable if `authjwt_token_location` is use cookies.
88

99
`authjwt_access_cookie_path`
1010
: What path should be set for the access cookie. Defaults to `'/'`, which will cause this
11-
access cookie to be sent in with every request.
11+
access cookie to be sent in every request.
1212

1313
`authjwt_refresh_cookie_path`
1414
: What path should be set for the refresh cookie. Defaults to `'/'`, which will cause this
15-
refresh cookie to be sent in with every request.
15+
refresh cookie to be sent in every request.
1616

1717
`authjwt_cookie_max_age`
1818
: If you don't set anything else, the cookie will expire when the browser is closed. Defaults to

examples/additional_claims.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from fastapi import FastAPI, HTTPException, Depends, Request
2+
from fastapi.responses import JSONResponse
3+
from fastapi_jwt_auth import AuthJWT
4+
from fastapi_jwt_auth.exceptions import AuthJWTException
5+
from pydantic import BaseModel
6+
7+
app = FastAPI()
8+
9+
class User(BaseModel):
10+
username: str
11+
password: str
12+
13+
class Settings(BaseModel):
14+
authjwt_secret_key: str = "secret"
15+
16+
@AuthJWT.load_config
17+
def get_config():
18+
return Settings()
19+
20+
@app.exception_handler(AuthJWTException)
21+
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
22+
return JSONResponse(
23+
status_code=exc.status_code,
24+
content={"detail": exc.message}
25+
)
26+
27+
@app.post('/login')
28+
def login(user: User, Authorize: AuthJWT = Depends()):
29+
if user.username != "test" or user.password != "test":
30+
raise HTTPException(status_code=401,detail="Bad username or password")
31+
32+
# You can be passing custom claim to argument user_claims
33+
# in function create_access_token() or create refresh token()
34+
another_claims = {"foo": ["fiz","baz"]}
35+
access_token = Authorize.create_access_token(subject=user.username,user_claims=another_claims)
36+
return {"access_token": access_token}
37+
38+
# In protected route, get the claims you added to the jwt with the
39+
# get_raw_jwt() method
40+
@app.get('/claims')
41+
def user(Authorize: AuthJWT = Depends()):
42+
Authorize.jwt_required()
43+
44+
foo_claims = Authorize.get_raw_jwt()['foo']
45+
return {"foo": foo_claims}

examples/basic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def authjwt_exception_handler(request: Request, exc: AuthJWTException):
3434
# later in endpoint protected
3535
@app.post('/login')
3636
def login(user: User, Authorize: AuthJWT = Depends()):
37-
if user.username != "test" and user.password != "test":
37+
if user.username != "test" or user.password != "test":
3838
raise HTTPException(status_code=401,detail="Bad username or password")
3939

4040
# subject identifier for who this token is for example id or username from database

0 commit comments

Comments
 (0)