mirror of
https://github.com/rjNemo/fastapi
synced 2026-06-12 13:36:41 +00:00
✨ Add docs for HTTP Basic Auth and tests (#177)
This commit is contained in:
parent
945f401d8e
commit
c705685394
6 changed files with 75 additions and 11 deletions
BIN
docs/img/tutorial/security/image12.png
Normal file
BIN
docs/img/tutorial/security/image12.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
11
docs/src/security/tutorial006.py
Normal file
11
docs/src/security/tutorial006.py
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
from fastapi import Depends, FastAPI
|
||||||
|
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
security = HTTPBasic()
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/users/me")
|
||||||
|
def read_current_user(credentials: HTTPBasicCredentials = Depends(security)):
|
||||||
|
return {"username": credentials.username, "password": credentials.password}
|
||||||
22
docs/src/security/tutorial007.py
Normal file
22
docs/src/security/tutorial007.py
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
from fastapi import Depends, FastAPI, HTTPException
|
||||||
|
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||||
|
from starlette.status import HTTP_401_UNAUTHORIZED
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
security = HTTPBasic()
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
|
||||||
|
if credentials.username != "foo" or credentials.password != "password":
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Incorrect email or password",
|
||||||
|
headers={"WWW-Authenticate": "Basic"},
|
||||||
|
)
|
||||||
|
return credentials.username
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/users/me")
|
||||||
|
def read_current_user(username: str = Depends(get_current_username)):
|
||||||
|
return {"username": username}
|
||||||
40
docs/tutorial/security/http-basic-auth.md
Normal file
40
docs/tutorial/security/http-basic-auth.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
For the simplest cases, you can use HTTP Basic Auth.
|
||||||
|
|
||||||
|
In HTTP Basic Auth, the application expects a header that contains a username and a password.
|
||||||
|
|
||||||
|
If it doesn't receive it, it returns an HTTP 401 "Unauthorized" error.
|
||||||
|
|
||||||
|
And returns a header `WWW-Authenticate` with a value of `Basic`, and an optional `realm` parameter.
|
||||||
|
|
||||||
|
That tells the browser to show the integrated prompt for a username and password.
|
||||||
|
|
||||||
|
Then, when you type that username and password, the browser sends them in the header automatically.
|
||||||
|
|
||||||
|
## Simple HTTP Basic Auth
|
||||||
|
|
||||||
|
* Import `HTTPBAsic` and `HTTPBasicCredentials`.
|
||||||
|
* Create a "`security` scheme" using `HTTPBAsic`.
|
||||||
|
* Use that `security` with a dependency in your *path operation*.
|
||||||
|
* It returns an object of type `HTTPBasicCredentials`:
|
||||||
|
* It contains the `username` and `password` sent.
|
||||||
|
|
||||||
|
|
||||||
|
```Python hl_lines="2 6 10"
|
||||||
|
{!./src/security/tutorial006.py!}
|
||||||
|
```
|
||||||
|
|
||||||
|
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
|
||||||
|
|
||||||
|
<img src="/img/tutorial/security/image12.png">
|
||||||
|
|
||||||
|
## Check the username
|
||||||
|
|
||||||
|
Here's a more complete example.
|
||||||
|
|
||||||
|
Use a dependency to check if the username and password are correct.
|
||||||
|
|
||||||
|
If the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:
|
||||||
|
|
||||||
|
```Python hl_lines="10 11 12 13 14 15 16 17 21"
|
||||||
|
{!./src/security/tutorial007.py!}
|
||||||
|
```
|
||||||
|
|
@ -58,6 +58,7 @@ nav:
|
||||||
- Simple OAuth2 with Password and Bearer: 'tutorial/security/simple-oauth2.md'
|
- Simple OAuth2 with Password and Bearer: 'tutorial/security/simple-oauth2.md'
|
||||||
- OAuth2 with Password (and hashing), Bearer with JWT tokens: 'tutorial/security/oauth2-jwt.md'
|
- OAuth2 with Password (and hashing), Bearer with JWT tokens: 'tutorial/security/oauth2-jwt.md'
|
||||||
- OAuth2 scopes: 'tutorial/security/oauth2-scopes.md'
|
- OAuth2 scopes: 'tutorial/security/oauth2-scopes.md'
|
||||||
|
- HTTP Basic Auth: 'tutorial/security/http-basic-auth.md'
|
||||||
- Middleware: 'tutorial/middleware.md'
|
- Middleware: 'tutorial/middleware.md'
|
||||||
- CORS (Cross-Origin Resource Sharing): 'tutorial/cors.md'
|
- CORS (Cross-Origin Resource Sharing): 'tutorial/cors.md'
|
||||||
- Using the Request Directly: 'tutorial/using-request-directly.md'
|
- Using the Request Directly: 'tutorial/using-request-directly.md'
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,9 @@
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
|
||||||
from fastapi import FastAPI, Security
|
|
||||||
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
|
||||||
from requests.auth import HTTPBasicAuth
|
from requests.auth import HTTPBasicAuth
|
||||||
from starlette.testclient import TestClient
|
from starlette.testclient import TestClient
|
||||||
|
|
||||||
app = FastAPI()
|
from security.tutorial006 import app
|
||||||
|
|
||||||
security = HTTPBasic()
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/users/me")
|
|
||||||
def read_current_user(credentials: HTTPBasicCredentials = Security(security)):
|
|
||||||
return {"username": credentials.username, "password": credentials.password}
|
|
||||||
|
|
||||||
|
|
||||||
client = TestClient(app)
|
client = TestClient(app)
|
||||||
|
|
||||||
Loading…
Reference in a new issue