Skip to content

๐Ÿ™… Oauth2๏ธโƒฃ โฎ๏ธ ๐Ÿ” & ๐Ÿ“จ

๐Ÿ”œ โžก๏ธ ๐Ÿ— โšช๏ธโžก๏ธ โฎ๏ธ ๐Ÿ“ƒ & ๐Ÿšฎ โŒ ๐Ÿ• โœ”๏ธ ๐Ÿ ๐Ÿ’‚โ€โ™‚ ๐Ÿ’ง.

๐Ÿคš username & password

๐Ÿ‘ฅ ๐Ÿ”œ โš™๏ธ FastAPI ๐Ÿ’‚โ€โ™‚ ๐Ÿš™ ๐Ÿคš username & password.

Oauth2๏ธโƒฃ โœ” ๐Ÿ‘ˆ ๐Ÿ•โ” โš™๏ธ "๐Ÿ” ๐Ÿ’ง" (๐Ÿ‘ˆ ๐Ÿ‘ฅ โš™๏ธ) ๐Ÿ‘ฉโ€๐Ÿ’ป/๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ”œ ๐Ÿ“จ username & password ๐Ÿ‘ ๐Ÿ“จ ๐Ÿ’ฝ.

& ๐Ÿ”Œ ๐Ÿ’ฌ ๐Ÿ‘ˆ ๐Ÿ‘ โœ”๏ธ ๐ŸŒŸ ๐Ÿ’– ๐Ÿ‘ˆ. user-name โš–๏ธ email ๐Ÿšซ๐Ÿ”œ ๐Ÿ‘ท.

โœ‹๏ธ ๐Ÿšซ ๐Ÿ˜Ÿ, ๐Ÿ‘† ๐Ÿ’ช ๐ŸŽฆ โšซ๏ธ ๐Ÿ‘† ๐ŸŽ‹ ๐Ÿ‘† ๐Ÿ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ•ธ.

& ๐Ÿ‘† ๐Ÿ’ฝ ๐Ÿท ๐Ÿ’ช โš™๏ธ ๐Ÿ™† ๐ŸŽ ๐Ÿ“› ๐Ÿ‘† ๐Ÿ’š.

โœ‹๏ธ ๐Ÿ’ณ โžก ๐Ÿ› ๏ธ, ๐Ÿ‘ฅ ๐Ÿ’ช โš™๏ธ ๐Ÿ‘‰ ๐Ÿ“› ๐Ÿ”— โฎ๏ธ ๐Ÿ”Œ (& ๐Ÿ’ช, ๐Ÿ–ผ, โš™๏ธ ๐Ÿ› ๏ธ ๐Ÿ› ๏ธ ๐Ÿงพ โš™๏ธ).

๐Ÿ”Œ ๐Ÿ‡ต๐Ÿ‡ธ ๐Ÿ‘ˆ username & password ๐Ÿ”œ ๐Ÿ“จ ๐Ÿ“จ ๐Ÿ’ฝ (, ๐Ÿ™…โ€โ™‚ ๐ŸŽป ๐Ÿ“ฅ).

scope

๐Ÿ”Œ ๐Ÿ’ฌ ๐Ÿ‘ˆ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ’ช ๐Ÿ“จ โž•1๏ธโƒฃ ๐Ÿ“จ ๐Ÿ‘ "scope".

๐Ÿ“จ ๐Ÿ‘ ๐Ÿ“› scope (โญ), โœ‹๏ธ โšซ๏ธ ๐Ÿค™ ๐Ÿ“ ๐ŸŽป โฎ๏ธ "โ†”" ๐ŸŽ ๐Ÿš€.

๐Ÿ”  "โ†”" ๐ŸŽป (๐Ÿต ๐Ÿš€).

๐Ÿ‘ซ ๐Ÿ›Ž โš™๏ธ ๐Ÿ“ฃ ๐ŸŽฏ ๐Ÿ’‚โ€โ™‚ โœ”, ๐Ÿ–ผ:

  • users:read โš–๏ธ users:write โš  ๐Ÿ–ผ.
  • instagram_basic โš™๏ธ ๐Ÿ‘ฑ๐Ÿ“” / ๐Ÿ‘ฑ๐Ÿ“”.
  • https://www.googleapis.com/auth/drive โš™๏ธ ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ”.

Info

Oauth2๏ธโƒฃ "โ†”" ๐ŸŽป ๐Ÿ‘ˆ ๐Ÿ“ฃ ๐ŸŽฏ โœ” โœ”.

โšซ๏ธ ๐Ÿšซ ๐Ÿค” ๐Ÿšฅ โšซ๏ธ โœ”๏ธ ๐ŸŽ ๐Ÿฆน ๐Ÿ’– : โš–๏ธ ๐Ÿšฅ โšซ๏ธ ๐Ÿ“›.

๐Ÿ‘ˆ โ„น ๐Ÿ› ๏ธ ๐ŸŽฏ.

Oauth2๏ธโƒฃ ๐Ÿ‘ซ ๐ŸŽป.

๐Ÿ“Ÿ ๐Ÿคš username & password

๐Ÿ”œ โžก๏ธ โš™๏ธ ๐Ÿš™ ๐Ÿšš FastAPI ๐Ÿต ๐Ÿ‘‰.

OAuth2PasswordRequestForm

๐Ÿฅ‡, ๐Ÿ—„ OAuth2PasswordRequestForm, & โš™๏ธ โšซ๏ธ ๐Ÿ”— โฎ๏ธ Depends โžก ๐Ÿ› ๏ธ /token:

from typing import Union

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Union[str, None] = None
    full_name: Union[str, None] = None
    disabled: Union[bool, None] = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: str | None = None
    full_name: str | None = None
    disabled: bool | None = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user

OAuth2PasswordRequestForm ๐ŸŽ“ ๐Ÿ”— ๐Ÿ‘ˆ ๐Ÿ“ฃ ๐Ÿ“จ ๐Ÿ’ช โฎ๏ธ:

  • username.
  • password.
  • ๐Ÿ“ฆ scope ๐Ÿ‘ ๐Ÿฆ ๐ŸŽป, โœ ๐ŸŽป ๐ŸŽ ๐Ÿš€.
  • ๐Ÿ“ฆ grant_type.

Tip

Oauth2๏ธโƒฃ ๐Ÿ”Œ ๐Ÿค™ ๐Ÿšš ๐Ÿ‘ grant_type โฎ๏ธ ๐Ÿ”ง ๐Ÿ’ฒ password, โœ‹๏ธ OAuth2PasswordRequestForm ๐Ÿšซ ๐Ÿ› ๏ธ โšซ๏ธ.

๐Ÿšฅ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ› ๏ธ โšซ๏ธ, โš™๏ธ OAuth2PasswordRequestFormStrict โ†ฉ๏ธ OAuth2PasswordRequestForm.

  • ๐Ÿ“ฆ client_id (๐Ÿ‘ฅ ๐Ÿšซ ๐Ÿ’ช โšซ๏ธ ๐Ÿ‘† ๐Ÿ–ผ).
  • ๐Ÿ“ฆ client_secret (๐Ÿ‘ฅ ๐Ÿšซ ๐Ÿ’ช โšซ๏ธ ๐Ÿ‘† ๐Ÿ–ผ).

Info

OAuth2PasswordRequestForm ๐Ÿšซ ๐ŸŽ ๐ŸŽ“ FastAPI OAuth2PasswordBearer.

OAuth2PasswordBearer โš’ FastAPI ๐Ÿ’ญ ๐Ÿ‘ˆ โšซ๏ธ ๐Ÿ’‚โ€โ™‚ โš–. โšซ๏ธ ๐Ÿšฎ ๐Ÿ‘ˆ ๐ŸŒŒ ๐Ÿ—„.

โœ‹๏ธ OAuth2PasswordRequestForm ๐ŸŽ“ ๐Ÿ”— ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช โœ”๏ธ โœ ๐Ÿ‘†, โš–๏ธ ๐Ÿ‘† ๐Ÿ’ช โœ”๏ธ ๐Ÿ“ฃ Form ๐Ÿ”ข ๐Ÿ”—.

โœ‹๏ธ โšซ๏ธ โš  โš™๏ธ ๐Ÿ’ผ, โšซ๏ธ ๐Ÿšš FastAPI ๐Ÿ”—, โš’ โšซ๏ธ โฉ.

โš™๏ธ ๐Ÿ“จ ๐Ÿ’ฝ

Tip

๐Ÿ‘ ๐Ÿ”— ๐ŸŽ“ OAuth2PasswordRequestForm ๐Ÿ† ๐Ÿšซ โœ”๏ธ ๐Ÿ”ข scope โฎ๏ธ ๐Ÿ“ ๐ŸŽป ๐Ÿ‘ฝ ๐Ÿš€, โ†ฉ๏ธ, โšซ๏ธ ๐Ÿ”œ โœ”๏ธ scopes ๐Ÿ”ข โฎ๏ธ โ˜‘ ๐Ÿ“‡ ๐ŸŽป ๐Ÿ”  โ†” ๐Ÿ“จ.

๐Ÿ‘ฅ ๐Ÿšซ โš™๏ธ scopes ๐Ÿ‘‰ ๐Ÿ–ผ, โœ‹๏ธ ๐Ÿ› ๏ธ ๐Ÿ“ค ๐Ÿšฅ ๐Ÿ‘† ๐Ÿ’ช โšซ๏ธ.

๐Ÿ”œ, ๐Ÿคš ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ“Š โšช๏ธโžก๏ธ (โŒ) ๐Ÿ’ฝ, โš™๏ธ username โšช๏ธโžก๏ธ ๐Ÿ“จ ๐Ÿ‘.

๐Ÿšฅ ๐Ÿ“ค ๐Ÿ™…โ€โ™‚ โœ… ๐Ÿ‘ฉโ€๐Ÿ’ป, ๐Ÿ‘ฅ ๐Ÿ“จ โŒ ๐Ÿ’ฌ "โŒ ๐Ÿ†” โš–๏ธ ๐Ÿ”".

โŒ, ๐Ÿ‘ฅ โš™๏ธ โš  HTTPException:

from typing import Union

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Union[str, None] = None
    full_name: Union[str, None] = None
    disabled: Union[bool, None] = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: str | None = None
    full_name: str | None = None
    disabled: bool | None = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user

โœ… ๐Ÿ”

๐Ÿ‘‰ โ˜ ๐Ÿ‘ฅ โœ”๏ธ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ“Š โšช๏ธโžก๏ธ ๐Ÿ‘† ๐Ÿ’ฝ, โœ‹๏ธ ๐Ÿ‘ฅ ๐Ÿšซ โœ… ๐Ÿ”.

โžก๏ธ ๐Ÿšฎ ๐Ÿ‘ˆ ๐Ÿ’ฝ Pydantic UserInDB ๐Ÿท ๐Ÿฅ‡.

๐Ÿ‘† ๐Ÿ”œ ๐Ÿ™… ๐Ÿ–Š ๐Ÿ”ข ๐Ÿ”,, ๐Ÿ‘ฅ ๐Ÿ”œ โš™๏ธ (โŒ) ๐Ÿ” ๐Ÿ” โš™๏ธ.

๐Ÿšฅ ๐Ÿ” ๐Ÿšซ ๐Ÿ, ๐Ÿ‘ฅ ๐Ÿ“จ ๐ŸŽ โŒ.

๐Ÿ” ๐Ÿ”

"๐Ÿ”" โ›“: ๐Ÿญ ๐ŸŽš (๐Ÿ” ๐Ÿ‘‰ ๐Ÿ’ผ) ๐Ÿ”˜ ๐Ÿ” ๐Ÿ”ข (๐ŸŽป) ๐Ÿ‘ˆ ๐Ÿ‘€ ๐Ÿ’– ๐Ÿ™ƒ.

๐Ÿ•โ” ๐Ÿ‘† ๐Ÿšถโ€โ™€๏ธ โšซ๏ธโ” ๐ŸŽ ๐ŸŽš (โšซ๏ธโ” ๐ŸŽ ๐Ÿ”) ๐Ÿ‘† ๐Ÿคš โšซ๏ธโ” ๐ŸŽ ๐Ÿ™ƒ.

โœ‹๏ธ ๐Ÿ‘† ๐Ÿšซ๐Ÿ”œ ๐Ÿ—œ โšช๏ธโžก๏ธ ๐Ÿ™ƒ ๐Ÿ”™ ๐Ÿ”.

โšซ๏ธโ” โš™๏ธ ๐Ÿ” ๐Ÿ”

๐Ÿšฅ ๐Ÿ‘† ๐Ÿ’ฝ ๐Ÿ“Ž, ๐Ÿง™โ€โ™€ ๐Ÿ† ๐Ÿšซ โœ”๏ธ ๐Ÿ‘† ๐Ÿ‘ฉโ€๐Ÿ’ป' ๐Ÿ”ข ๐Ÿ”, ๐Ÿ•ด#๏ธโƒฃ.

, ๐Ÿง™โ€โ™€ ๐Ÿ† ๐Ÿšซ ๐Ÿ’ช ๐Ÿ”„ โš™๏ธ ๐Ÿ‘ˆ ๐ŸŽ ๐Ÿ” โž•1๏ธโƒฃ โš™๏ธ (๐Ÿ“š ๐Ÿ‘ฉโ€๐Ÿ’ป โš™๏ธ ๐ŸŽ ๐Ÿ” ๐ŸŒ, ๐Ÿ‘‰ ๐Ÿ”œ โš ).

from typing import Union

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Union[str, None] = None
    full_name: Union[str, None] = None
    disabled: Union[bool, None] = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: str | None = None
    full_name: str | None = None
    disabled: bool | None = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user

๐Ÿ”ƒ **user_dict

UserInDB(**user_dict) โ›“:

๐Ÿšถโ€โ™€๏ธ ๐Ÿ”‘ & ๐Ÿ’ฒ user_dict ๐Ÿ”— ๐Ÿ”‘-๐Ÿ’ฒ โŒ, ๐ŸŒ“:

UserInDB(
    username = user_dict["username"],
    email = user_dict["email"],
    full_name = user_dict["full_name"],
    disabled = user_dict["disabled"],
    hashed_password = user_dict["hashed_password"],
)

Info

๐ŸŒ… ๐Ÿ ๐Ÿ”‘ **๐Ÿ‘ฉโ€๐Ÿ’ป_ #๏ธโƒฃ โœ… ๐Ÿ”™ ๐Ÿงพ โž• ๐Ÿท.

๐Ÿ“จ ๐Ÿค

๐Ÿ“จ token ๐Ÿ”— ๐Ÿ”œ ๐ŸŽป ๐ŸŽš.

โšซ๏ธ ๐Ÿ”œ โœ”๏ธ token_type. ๐Ÿ‘† ๐Ÿ’ผ, ๐Ÿ‘ฅ โš™๏ธ "๐Ÿ“จ" ๐Ÿค, ๐Ÿค ๐Ÿ†Ž ๐Ÿ”œ "bearer".

& โšซ๏ธ ๐Ÿ”œ โœ”๏ธ access_token, โฎ๏ธ ๐ŸŽป โš— ๐Ÿ‘† ๐Ÿ” ๐Ÿค.

๐Ÿ‘‰ ๐Ÿ™… ๐Ÿ–ผ, ๐Ÿ‘ฅ ๐Ÿ”œ ๐Ÿ• ๐Ÿ˜Ÿ & ๐Ÿ“จ ๐ŸŽ username ๐Ÿค.

Tip

โญ ๐Ÿ“ƒ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ ๐ŸŽฐ ๐Ÿ” ๐Ÿ› ๏ธ, โฎ๏ธ ๐Ÿ” #๏ธโƒฃ & ๐Ÿฅ™ ๐Ÿค.

โœ‹๏ธ ๐Ÿ”œ, โžก๏ธ ๐ŸŽฏ ๐Ÿ”› ๐ŸŽฏ โ„น ๐Ÿ‘ฅ ๐Ÿ’ช.

from typing import Union

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Union[str, None] = None
    full_name: Union[str, None] = None
    disabled: Union[bool, None] = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: str | None = None
    full_name: str | None = None
    disabled: bool | None = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user

Tip

๐Ÿ”Œ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ“จ ๐ŸŽป โฎ๏ธ access_token & token_type, ๐ŸŽ ๐Ÿ‘‰ ๐Ÿ–ผ.

๐Ÿ‘‰ ๐Ÿ•ณ ๐Ÿ‘ˆ ๐Ÿ‘† โœ”๏ธ ๐Ÿ‘† ๐Ÿ‘† ๐Ÿ“Ÿ, & โš’ ๐Ÿ’ญ ๐Ÿ‘† โš™๏ธ ๐Ÿ“š ๐ŸŽป ๐Ÿ”‘.

โšซ๏ธ ๐ŸŒ– ๐Ÿ•ด ๐Ÿ‘œ ๐Ÿ‘ˆ ๐Ÿ‘† โœ”๏ธ ๐Ÿ’ญ โ˜‘ ๐Ÿ‘†, ๐Ÿ› ๏ธ โฎ๏ธ ๐Ÿ”ง.

๐ŸŽ‚, FastAPI ๐Ÿต โšซ๏ธ ๐Ÿ‘†.

โ„น ๐Ÿ”—

๐Ÿ”œ ๐Ÿ‘ฅ ๐Ÿ”œ โ„น ๐Ÿ‘† ๐Ÿ”—.

๐Ÿ‘ฅ ๐Ÿ’š ๐Ÿคš current_user ๐Ÿ•ด ๐Ÿšฅ ๐Ÿ‘‰ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿฆ.

, ๐Ÿ‘ฅ โœ ๐ŸŒ– ๐Ÿ”— get_current_active_user ๐Ÿ‘ˆ ๐Ÿ”„ โš™๏ธ get_current_user ๐Ÿ”—.

๐Ÿ‘ฏโ€โ™‚๏ธ ๐Ÿ‘‰ ๐Ÿ”— ๐Ÿ”œ ๐Ÿ“จ ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” โŒ ๐Ÿšฅ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿšซ ๐Ÿ”€, โš–๏ธ ๐Ÿšฅ ๐Ÿ”•.

, ๐Ÿ‘† ๐Ÿ”—, ๐Ÿ‘ฅ ๐Ÿ”œ ๐Ÿ•ด ๐Ÿคš ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿšฅ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ”€, โ˜‘ ๐Ÿ”“, & ๐Ÿฆ:

from typing import Union

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: Union[str, None] = None
    full_name: Union[str, None] = None
    disabled: Union[bool, None] = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel

fake_users_db = {
    "johndoe": {
        "username": "johndoe",
        "full_name": "John Doe",
        "email": "johndoe@example.com",
        "hashed_password": "fakehashedsecret",
        "disabled": False,
    },
    "alice": {
        "username": "alice",
        "full_name": "Alice Wonderson",
        "email": "alice@example.com",
        "hashed_password": "fakehashedsecret2",
        "disabled": True,
    },
}

app = FastAPI()


def fake_hash_password(password: str):
    return "fakehashed" + password


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")


class User(BaseModel):
    username: str
    email: str | None = None
    full_name: str | None = None
    disabled: bool | None = None


class UserInDB(User):
    hashed_password: str


def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)


def fake_decode_token(token):
    # This doesn't provide any security at all
    # Check the next version
    user = get_user(fake_users_db, token)
    return user


async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_decode_token(token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )
    return user


async def get_current_active_user(current_user: User = Depends(get_current_user)):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user


@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    user_dict = fake_users_db.get(form_data.username)
    if not user_dict:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    user = UserInDB(**user_dict)
    hashed_password = fake_hash_password(form_data.password)
    if not hashed_password == user.hashed_password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")

    return {"access_token": user.username, "token_type": "bearer"}


@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_active_user)):
    return current_user

Info

๐ŸŒ– ๐ŸŽš WWW-Authenticate โฎ๏ธ ๐Ÿ’ฒ Bearer ๐Ÿ‘ฅ ๐Ÿ›ฌ ๐Ÿ“ฅ ๐Ÿ• ๐Ÿ”Œ.

๐Ÿ™† ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” (โŒ) ๐Ÿ‘” ๐Ÿ“Ÿ 4๏ธโƒฃ0๏ธโƒฃ1๏ธโƒฃ "โ›”" ๐Ÿค” ๐Ÿ“จ WWW-Authenticate ๐ŸŽš.

๐Ÿ’ผ ๐Ÿ“จ ๐Ÿค (๐Ÿ‘† ๐Ÿ’ผ), ๐Ÿ’ฒ ๐Ÿ‘ˆ ๐ŸŽš ๐Ÿ”œ Bearer.

๐Ÿ‘† ๐Ÿ’ช ๐Ÿค™ ๐Ÿšถ ๐Ÿ‘ˆ โž• ๐ŸŽš & โšซ๏ธ ๐Ÿ”œ ๐Ÿ‘ท.

โœ‹๏ธ โšซ๏ธ ๐Ÿšš ๐Ÿ“ฅ ๐Ÿ› ๏ธ โฎ๏ธ ๐Ÿ”ง.

, ๐Ÿ“ค 5๏ธโƒฃ๐Ÿ“† ๐Ÿงฐ ๐Ÿ‘ˆ โŒ› & โš™๏ธ โšซ๏ธ (๐Ÿ”œ โš–๏ธ ๐Ÿ”ฎ) & ๐Ÿ‘ˆ ๐Ÿ’ช โš  ๐Ÿ‘† โš–๏ธ ๐Ÿ‘† ๐Ÿ‘ฉโ€๐Ÿ’ป, ๐Ÿ”œ โš–๏ธ ๐Ÿ”ฎ.

๐Ÿ‘ˆ ๐Ÿ’ฐ ๐Ÿฉ...

๐Ÿ‘€ โšซ๏ธ ๐ŸŽฏ

๐Ÿ“‚ ๐ŸŽ“ ๐Ÿฉบ: http://127.0.0.1:8000/docs.

๐Ÿ”“

๐Ÿ–Š "โœ”" ๐Ÿ”ผ.

โš™๏ธ ๐ŸŽ“:

๐Ÿ‘ฉโ€๐Ÿ’ป: johndoe

๐Ÿ”: secret

โฎ๏ธ ๐Ÿ”— โš™๏ธ, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ โšซ๏ธ ๐Ÿ’–:

๐Ÿคš ๐Ÿ‘† ๐Ÿ‘ ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ’ฝ

๐Ÿ”œ โš™๏ธ ๐Ÿ› ๏ธ GET โฎ๏ธ โžก /users/me.

๐Ÿ‘† ๐Ÿ”œ ๐Ÿคš ๐Ÿ‘† ๐Ÿ‘ฉโ€๐Ÿ’ป ๐Ÿ“Š, ๐Ÿ’–:

{
  "username": "johndoe",
  "email": "johndoe@example.com",
  "full_name": "John Doe",
  "disabled": false,
  "hashed_password": "fakehashedsecret"
}

๐Ÿšฅ ๐Ÿ‘† ๐Ÿ–Š ๐Ÿ”’ โ„น & โ, & โคด๏ธ ๐Ÿ”„ ๐ŸŽ ๐Ÿ› ๏ธ ๐Ÿ”„, ๐Ÿ‘† ๐Ÿ”œ ๐Ÿคš ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” 4๏ธโƒฃ0๏ธโƒฃ1๏ธโƒฃ โŒ:

{
  "detail": "Not authenticated"
}

๐Ÿ”• ๐Ÿ‘ฉโ€๐Ÿ’ป

๐Ÿ”œ ๐Ÿ”„ โฎ๏ธ ๐Ÿ”• ๐Ÿ‘ฉโ€๐Ÿ’ป, ๐Ÿ”“ โฎ๏ธ:

๐Ÿ‘ฉโ€๐Ÿ’ป: alice

๐Ÿ”: secret2

& ๐Ÿ”„ โš™๏ธ ๐Ÿ› ๏ธ GET โฎ๏ธ โžก /users/me.

๐Ÿ‘† ๐Ÿ”œ ๐Ÿคš "๐Ÿ”• ๐Ÿ‘ฉโ€๐Ÿ’ป" โŒ, ๐Ÿ’–:

{
  "detail": "Inactive user"
}

๐ŸŒƒ

๐Ÿ‘† ๐Ÿ”œ โœ”๏ธ ๐Ÿงฐ ๐Ÿ› ๏ธ ๐Ÿ ๐Ÿ’‚โ€โ™‚ โš™๏ธ โš“๏ธ ๐Ÿ”› username & password ๐Ÿ‘† ๐Ÿ› ๏ธ.

โš™๏ธ ๐Ÿ‘ซ ๐Ÿงฐ, ๐Ÿ‘† ๐Ÿ’ช โš’ ๐Ÿ’‚โ€โ™‚ โš™๏ธ ๐Ÿ”— โฎ๏ธ ๐Ÿ™† ๐Ÿ’ฝ & โฎ๏ธ ๐Ÿ™† ๐Ÿ‘ฉโ€๐Ÿ’ป โš–๏ธ ๐Ÿ’ฝ ๐Ÿท.

๐Ÿ•ด โ„น โŒ ๐Ÿ‘ˆ โšซ๏ธ ๐Ÿšซ ๐Ÿค™ "๐Ÿ”".

โญ ๐Ÿ“ƒ ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ‘€ โ” โš™๏ธ ๐Ÿ” ๐Ÿ” ๐Ÿ” ๐Ÿ—ƒ & ๐Ÿฅ™ ๐Ÿค.