๐ 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
๐ ๐ ๏ธ.
โ๏ธ ๐ซ ๐งฐ, ๐ ๐ช โ ๐โโ โ๏ธ ๐ โฎ๏ธ ๐ ๐ฝ & โฎ๏ธ ๐ ๐ฉโ๐ป โ๏ธ ๐ฝ ๐ท.
๐ด โน โ ๐ โซ๏ธ ๐ซ ๐ค "๐".
โญ ๐ ๐ ๐ ๐ โ โ๏ธ ๐ ๐ ๐ ๐ & ๐ฅ ๐ค.