Skip to content

🇺🇸🔍 🔰 🔐

🙅 💼, 👆 💪 ⚙️ 🇺🇸🔍 🔰 🔐.

🇺🇸🔍 🔰 🔐, 🈸 ⌛ 🎚 👈 🔌 🆔 & 🔐.

🚥 ⚫️ 🚫 📨 ⚫️, ⚫️ 📨 🇺🇸🔍 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 username 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 username 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}