728x90
HTML 렌더링을 API로 만들어서 호출해 보자
FastAPI에서 직접 HTML로 응답을 반환하려면 HTMLResponse 사용한다.
HTMLResponse의 매개변수 response_class로 전달한다.
1. todos.py 수정
import sys
sys.path.append("..")
from fastapi import APIRouter, Request
import models
from database import engine, SessionLocal
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
router = APIRouter(
prefix="/todos",
tags=['todos'],
responses={404: {"description": "Not found"}}
)
models.Base.metadata.create_all(bind=engine)
templates = Jinja2Templates(directory="templates")
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("/", response_class=HTMLResponse)
async def read_all_by_user(request: Request):
return templates.TemplateResponse("home.html", {"request":request})
@router.get("/add-todo", response_class=HTMLResponse)
async def add_new_todo(request: Request):
return templates.TemplateResponse("add-todo.html", {"request":request})
@router.get("/edit-todo/{todo_id}", response_class=HTMLResponse)
async def edit_todo(request: Request):
return templates.TemplateResponse("edit-todo.html", {"request":request})
2. 사이트 확인
3. auth.py 수정
import sys
sys.path.append('..')
from fastapi import Depends, HTTPException, status, APIRouter, Request
from pydantic import BaseModel
from typing import Optional
import models
from passlib.context import CryptContext
from sqlalchemy.orm import Session
from database import SessionLocal, engine
from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer
from datetime import datetime, timedelta
from jose import jwt, JWTError
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
SECRET_KEY = "{SECRET_KEY}"
ALGORITHM = "HS256"
templates = Jinja2Templates(directory="templates")
class CreateUser(BaseModel):
username: str
email: Optional[str]
first_name: str
last_name: str
password: str
phone_number: Optional[str]
bcrypt_context = CryptContext(schemes=['bcrypt'], deprecated="auto")
models.Base.metadata.create_all(bind=engine)
oauth2_bearer = OAuth2PasswordBearer(tokenUrl="token")
router = APIRouter(
prefix="/auth",
tags=["auth"],
responses={401: {"user": "Not authorized"}}
)
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
def get_password_hash(password):
return bcrypt_context.hash(password)
def verify_password(plain_password, hashed_password):
return bcrypt_context.verify(plain_password, hashed_password)
def authenticate_user(username: str, password: str, db):
user = db.query(models.Users).filter(models.Users.username == username).first()
if not user:
return False
if not verify_password(password, user.hashed_password):
return False
return user
def create_access_token(username: str, user_id: int, expires_delta: Optional[timedelta] = None):
encode = {"sub": username, "id": user_id}
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
encode.update({"exp": expire})
return jwt.encode(encode, SECRET_KEY, algorithm=ALGORITHM)
def get_user_exception():
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate":"Bearer"},
)
return credentials_exception
def token_exception():
token_exception_response = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate":"Bearer"},
)
return token_exception_response
async def get_current_user(token: str = Depends(oauth2_bearer)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
user_id: int = payload.get("id")
if username is None or user_id is None:
raise get_user_exception()
return {"username": username, "id": user_id}
except JWTError:
return get_user_exception()
#로그인, 회원가입 API 생성
@router.get("/", response_class=HTMLResponse)
async def authentication_page(request: Request):
return templates.TemplateResponse("login.html", {"request":request})
@router.get("/register", response_class=HTMLResponse)
async def register(request:Request):
return templates.TemplateResponse("register.html", {"request":request})
@router.post("/create/user")
async def create_new_user(create_user: CreateUser, db: Session = Depends(get_db)):
create_user_model = models.Users()
create_user_model.email = create_user.email
create_user_model.username = create_user.username
create_user_model.first_name = create_user.first_name
create_user_model.last_name = create_user.last_name
create_user_model.phone_number = create_user.phone_number
hash_password = get_password_hash(create_user.password)
create_user_model.hashed_password = hash_password
create_user_model.is_active = True
db.add(create_user_model)
db.flush()
db.commit()
@router.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(),
db: Session = Depends(get_db)):
user = authenticate_user(form_data.username, form_data.password, db)
if not user:
return token_exception()
token_expires = timedelta(minutes=20)
token = create_access_token(user.username,
user.id,
expires_delta=token_expires)
return {"token": token}
4. 사이트 확인
728x90
SMALL
'Develop > FastAPI' 카테고리의 다른 글
FastAPI 프로젝트 진행(추가 레이아웃, 추상화) - 83 (0) | 2023.01.26 |
---|---|
FastAPI 프로젝트 진행(레이아웃) - 82 (0) | 2023.01.26 |
FastAPI 프로젝트 진행(로그인, 회원가입 프론트 구현) - 80 (0) | 2023.01.25 |
FastAPI 프로젝트 진행(form 생성 / 수정) - 79 (0) | 2023.01.25 |
FastAPI 프로젝트 진행(Navbar, Table 프론트 구현) - 78 (0) | 2023.01.25 |