๐บ๐ธ๐ ๐ฐ ๐¶
๐ ๐ผ, ๐ ๐ช โ๏ธ ๐บ๐ธ๐ ๐ฐ ๐.
๐บ๐ธ๐ ๐ฐ ๐, ๐ธ โ ๐ ๐ ๐ ๐ & ๐.
๐ฅ โซ๏ธ ๐ซ ๐จ โซ๏ธ, โซ๏ธ ๐จ ๐บ๐ธ๐ 4๏ธโฃ0๏ธโฃ1๏ธโฃ "โ" โ.
& ๐จ ๐ WWW-Authenticate
โฎ๏ธ ๐ฒ Basic
, & ๐ฆ realm
๐ข.
๐ ๐ฌ ๐ฅ ๐ฆ ๐ ๏ธ ๐ ๐ & ๐.
โคด๏ธ, ๐โ ๐ ๐ ๐ ๐ & ๐, ๐ฅ ๐จ ๐ซ ๐ ๐.
๐ ๐บ๐ธ๐ ๐ฐ ๐¶
- ๐
HTTPBasic
&HTTPBasicCredentials
. - โ "
security
โ" โ๏ธHTTPBasic
. - โ๏ธ ๐
security
โฎ๏ธ ๐ ๐ โก ๐ ๏ธ. - โซ๏ธ ๐จ ๐ ๐
HTTPBasicCredentials
:- โซ๏ธ ๐
username
&password
๐จ.
- โซ๏ธ ๐
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}
๐โ ๐ ๐ ๐ ๐ ๐ฅ ๐ฐ (โ๏ธ ๐ "๐ ๏ธ" ๐ผ ๐ฉบ) ๐ฅ ๐ ๐ญ ๐ ๐ ๐ & ๐:
โ ๐¶
๐ฅ ๐ ๐ ๐ผ.
โ๏ธ ๐ โ ๐ฅ ๐ & ๐ โ.
๐, โ๏ธ ๐ ๐ฉ ๐น secrets
โ
๐ & ๐.
secrets.compare_digest()
๐ช โ bytes
โ๏ธ str
๐ ๐ด ๐ ๐ ๐ฆน (๐ ๐ช๐ธ), ๐ โ โซ๏ธ ๐ซ๐ ๐ท โฎ๏ธ ๐ฆน ๐ รก
, Sebastiรกn
.
๐ต ๐, ๐ฅ ๐ฅ ๐ username
& password
bytes
๐ข ๐ซ โฎ๏ธ ๐ -8๏ธโฃ.
โคด๏ธ ๐ฅ ๐ช โ๏ธ secrets.compare_digest()
๐ ๐ credentials.username
"stanleyjobson"
, & ๐ credentials.password
"swordfish"
.
import secrets
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
current_username_bytes = credentials.username.encode("utf8")
correct_username_bytes = b"stanleyjobson"
is_correct_username = secrets.compare_digest(
current_username_bytes, correct_username_bytes
)
current_password_bytes = credentials.password.encode("utf8")
correct_password_bytes = b"swordfish"
is_correct_password = secrets.compare_digest(
current_password_bytes, correct_password_bytes
)
if not (is_correct_username and is_correct_password):
raise HTTPException(
status_code=status.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}
๐ ๐ ๐:
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# Return some error
...
โ๏ธ โ๏ธ secrets.compare_digest()
โซ๏ธ ๐ ๐ ๐ก ๐ ๐ ๐ค "๐ฐ ๐".
โฒ ๐¶
โ๏ธ โซ๏ธโ "โฒ ๐"โ
โก๏ธ ๐ ๐ ๐ ๐ญ ๐ & ๐.
& ๐ซ ๐จ ๐จ โฎ๏ธ ๐ johndoe
& ๐ love123
.
โคด๏ธ ๐ ๐ ๐ ๐ธ ๐ ๐ ๐ณ ๐:
if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
...
โ๏ธ โถ๏ธ๏ธ ๐ ๐ ๐ฌ ๐ฅ j
johndoe
๐ฅ s
stanleyjobson
, โซ๏ธ ๐ ๐จ False
, โฉ๏ธ โซ๏ธ โช ๐ญ ๐ ๐ 2๏ธโฃ ๐ป ๐ซ ๐, ๐ญ ๐ "๐ค ๐
โโ ๐ช ๐ ๐
๐ โ ๐ ๐ค". & ๐ ๐ธ ๐ ๐ฌ "โ ๐ฉโ๐ป โ๏ธ ๐".
โ๏ธ โคด๏ธ ๐ ๐ โฎ๏ธ ๐ stanleyjobsox
& ๐ love123
.
& ๐ ๐ธ ๐ ๐จ ๐ณ ๐:
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
...
๐ ๐ โ๏ธ ๐ฌ ๐ stanleyjobso
๐ฏโโ๏ธ stanleyjobsox
& stanleyjobson
โญ ๐ค ๐ ๐ฏโโ๏ธ ๐ป ๐ซ ๐. โซ๏ธ ๐ โ โ โฒ ๐จ ๐ "โ ๐ฉโ๐ป โ๏ธ ๐".
๐ฐ โ โน ๐¶
๐ โ, ๐ ๐ ๐ฝ โ โฒ ๐ ๐จ "โ ๐ฉโ๐ป โ๏ธ ๐" ๐จ, ๐ ๐ ๐ญ ๐ ๐ซ ๐ค ๐ณ โถ๏ธ๏ธ, โถ๏ธ ๐ค โถ๏ธ๏ธ.
& โคด๏ธ ๐ซ ๐ช ๐ ๐ ๐ค ๐ โซ๏ธ ๐ฒ ๐ณ ๐ ๐ stanleyjobsox
๐ johndoe
.
"๐ด" ๐¶
โ๏ธ, ๐ ๐ ๐ซ ๐ ๐ ๐ โ, ๐ซ ๐ โ ๐ โซ๏ธ, ๐ฒ โฎ๏ธ ๐ฏ โ๏ธ ๐ฏ ๐ฏ ๐ ๐ฅ. & ๐ ๐ค 1๏ธโฃ โ โ ๐ค ๐ฐ.
โ๏ธ ๐จ ๐, โฒ โ๏ธ ๐ ๐ ๐ โ๏ธ ๐ญ โ ๐ & ๐, โฎ๏ธ "โน" ๐ ๐ธ, โ๏ธ ๐ฐ โ โ.
๐ง โซ๏ธ โฎ๏ธ secrets.compare_digest()
¶
โ๏ธ ๐ ๐ ๐ฅ ๐ค โ๏ธ secrets.compare_digest()
.
๐, โซ๏ธ ๐ โ ๐ ๐ฐ ๐ฌ stanleyjobsox
stanleyjobson
๐ โซ๏ธ โ ๐ฌ johndoe
stanleyjobson
. & ๐ ๐.
๐ ๐, โ๏ธ secrets.compare_digest()
๐ ๐ธ ๐, โซ๏ธ ๐ ๐ ๐ก ๐ ๐ โ ๐โโ ๐.
๐จ โ¶
โฎ๏ธ ๐ ๐ ๐ โ, ๐จ HTTPException
โฎ๏ธ ๐ ๐ 4๏ธโฃ0๏ธโฃ1๏ธโฃ (๐ ๐จ ๐โ ๐
โโ ๐ ๐) & ๐ฎ ๐ WWW-Authenticate
โ ๐ฅ ๐ฆ ๐ณ ๐ ๐:
import secrets
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
current_username_bytes = credentials.username.encode("utf8")
correct_username_bytes = b"stanleyjobson"
is_correct_username = secrets.compare_digest(
current_username_bytes, correct_username_bytes
)
current_password_bytes = credentials.password.encode("utf8")
correct_password_bytes = b"swordfish"
is_correct_password = secrets.compare_digest(
current_password_bytes, correct_password_bytes
)
if not (is_correct_username and is_correct_password):
raise HTTPException(
status_code=status.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}