Skip to content

Commit c4751fa

Browse files
committed
add asymmetric docs
1 parent d38854d commit c4751fa

File tree

4 files changed

+91
-2
lines changed

4 files changed

+91
-2
lines changed

docs/advanced-usage/asymmetric.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Usage of RSA `RS*` and EC `EC*` algorithms require a basic understanding of how public-key cryptography is used with regards to digital signatures. If you are familiar with that, you may want to use this.
2+
3+
```python hl_lines="9-33 42-44"
4+
{!../examples/asymmetric.py!}
5+
```

docs/configuration/general.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
: The secret key needed for symmetric based signing algorithms, such as `HS*`. Defaults to `None`
88

99
`authjwt_public_key`
10-
: The public key needed for asymmetric based signing algorithms, such as `RS*` or `ES*`. PEM format expected.
10+
: The public key needed for asymmetric based signing algorithms, such as `RS*` or `EC*`. PEM format expected.
1111
Defaults to `None`
1212

1313
`authjwt_private_key`
14-
: The private key needed for asymmetric based signing algorithms, such as `RS*` or `ES*`. PEM format expected.
14+
: The private key needed for asymmetric based signing algorithms, such as `RS*` or `EC*`. PEM format expected.
1515
Defaults to `None`
1616

1717
`authjwt_algorithm`

examples/asymmetric.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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+
# In the real case, you can put the
8+
# public key and private key in *.txt then you can read that file
9+
private_key = """
10+
-----BEGIN RSA PRIVATE KEY-----
11+
MIICWwIBAAKBgGBoQhqHdMU65aSBQVC/u9a6HMfKA927aZOk7HA/kXuA5UU4Sl+U
12+
C9WjDhMQFk1PpqAjZdCqx9ajolTYnIfeaVHcLNpJQ6QXLnUyMnfwPmwYQ2rkuy5w
13+
I2NdO81CzJ/9S8MsPyMl2/CF9ZxM03eleE8RKFwXCxZ/IoiqN4jVNjSrAgMBAAEC
14+
gYAnNqEUq146zx8TT6PilWpxB9inByuVaCKkdGPbsG+bfa1D/4Z44/4AUsdpx5Ra
15+
s/hBkMRcIOsSChMAUe8xcK0DqA9Y7BIVfpma2fH/gYq6dP3dOfCxftZBF00HwIu7
16+
5e7RWnBC8MkPnrkKdHq6ptAYlGgoSJTEQREqusDiuNG9yQJBAKQib2VhNAqgyvvi
17+
PdmFrCqq15z9MY16WCfttuqfAaSYKHnZe1WvBKbSNW9x4Cgjfhzl9mlozlW4rob/
18+
ttPN6e0CQQCWXbVtqmVdB5Ol9wQN7DIRc8q5F8HKQqIJAMTmwaRwNDsGRxCWMwGO
19+
8WAlnejzYTXmrrytv6kXX8U40enJW2X3AkAI42h+5/WmgbCcVVMeHXQGV3wXn0p4
20+
q+BsQR4/tF6laCwA9TsNl827rvR/1X3bDpj8vaNLcAaEc9zXqK9g5uy9AkATeOkw
21+
3Xso8/075eRBhU/qkKs1Ew2GiuB+9/mHxJXt7eWi53sPaGWQRFPmKy/qrLEVQZWv
22+
jn1wSHe65vw2lj57AkEAh04n1wrZnCha8s6crMhjggdTXI6G4FU3TGf8ssGboqs3
23+
j5lemvyKod+u2JVKwarcKmd/gFYBOjsRm18LlZH74A==
24+
-----END RSA PRIVATE KEY-----
25+
"""
26+
public_key = """
27+
-----BEGIN PUBLIC KEY-----
28+
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGBoQhqHdMU65aSBQVC/u9a6HMfK
29+
A927aZOk7HA/kXuA5UU4Sl+UC9WjDhMQFk1PpqAjZdCqx9ajolTYnIfeaVHcLNpJ
30+
Q6QXLnUyMnfwPmwYQ2rkuy5wI2NdO81CzJ/9S8MsPyMl2/CF9ZxM03eleE8RKFwX
31+
CxZ/IoiqN4jVNjSrAgMBAAE=
32+
-----END PUBLIC KEY-----
33+
"""
34+
35+
app = FastAPI()
36+
37+
class User(BaseModel):
38+
username: str
39+
password: str
40+
41+
class Settings(BaseModel):
42+
authjwt_algorithm: str = "RS512"
43+
authjwt_public_key: str = public_key
44+
authjwt_private_key: str = private_key
45+
46+
@AuthJWT.load_config
47+
def get_config():
48+
return Settings()
49+
50+
@app.exception_handler(AuthJWTException)
51+
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
52+
return JSONResponse(
53+
status_code=exc.status_code,
54+
content={"detail": exc.message}
55+
)
56+
57+
@app.post('/login')
58+
def login(user: User, Authorize: AuthJWT = Depends()):
59+
if user.username != "test" or user.password != "test":
60+
raise HTTPException(status_code=401,detail="Bad username or password")
61+
62+
access_token = Authorize.create_access_token(subject=user.username)
63+
refresh_token = Authorize.create_refresh_token(subject=user.username)
64+
return {"access_token": access_token, "refresh_token": refresh_token}
65+
66+
@app.post('/refresh')
67+
def refresh(Authorize: AuthJWT = Depends()):
68+
Authorize.jwt_refresh_token_required()
69+
70+
current_user = Authorize.get_jwt_subject()
71+
new_access_token = Authorize.create_access_token(subject=current_user)
72+
return {"access_token": new_access_token}
73+
74+
@app.get('/protected')
75+
def protected(Authorize: AuthJWT = Depends()):
76+
Authorize.jwt_required()
77+
78+
current_user = Authorize.get_jwt_subject()
79+
return {"user": current_user}

mkdocs.yml

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ theme:
88
repo_name: IndominusByte/fastapi-jwt-auth
99
repo_url: https://github.com/IndominusByte/fastapi-jwt-auth
1010

11+
google_analytics:
12+
- G-P08KBZV1K6
13+
- auto
14+
1115
markdown_extensions:
1216
- markdown_include.include:
1317
base_path: docs
@@ -40,6 +44,7 @@ nav:
4044
- JWT in Cookies: usage/jwt-in-cookies.md
4145
- Advanced Usage:
4246
- Additional claims: advanced-usage/additional-claims.md
47+
- Asymmetric Algorithm: advanced-usage/asymmetric.md
4348
- Dynamic Token Expires: advanced-usage/dynamic-expires.md
4449
- Dynamic Token Algorithm: advanced-usage/dynamic-algorithm.md
4550
- Bigger Applications: advanced-usage/bigger-app.md

0 commit comments

Comments
 (0)