FastAPI 프로젝트 진행(비밀번호 변경, 라우터 추가) - 95

2023. 1. 31. 21:54·Develop/FastAPI
728x90
SMALL

프로젝트 디렉터리 구조

fastapi
todoapp
main.py

database.py

models.py

todos.db
templates static routers
todo
css js
home.html

add-todo.html

edit-todo.html

login.html

register.html

layout.html

navbar.html

edit-user-password.html
base.css

bootstrap.css
bootstrap.js

jquery-slim.js

popper.js
auth.py

todos.py

users.py
templates 하위에 edit-user-password.html 생성
routers 하위에 users.py 생성

 

1. users.py 기본 세팅

import sys
sys.path.append("..")

from starlette import status
from starlette.responses import RedirectResponse
from fastapi import Depends, APIRouter, Request, Form
import models
from database import engine, SessionLocal
from sqlalchemy.orm import Session
from pydantic import BaseModel
from .auth import get_current_user, verify_password, get_password_hash

from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates


router = APIRouter(
    prefix="/users",
    tags=["users"],
    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()


class UserVerification(BaseModel):
    username: str
    password: str
    new_password: str
UserVerification 클래스: 파싱 and 유효성 검사
get_db 함수: DB 연결

 

2. users.py GET API 생성

@router.get("/edit-password", response_class=HTMLResponse)
async def edit_user_view(request: Request):

    user = await get_current_user(request)
    if user is None:
        return RedirectResponse(url="/auth", status_code=status.HTTP_302_FOUND)

    return templates.TemplateResponse("edit-user-password.html", {"request": request, "user": user})

 

3. navbar.html 수정

<div>
    <nav class="navbar navbar-expand-md navbar-dark main-color fixed-top">
        <a class="navbar-brand" href="#">Todo App</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
                aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav" ...>

           <ul class="navbar-nav ml-auto">
              {% if user %}
              
              <!--패스워드 수정 버튼 생성-->
              <li class="nav-item m-1">
                 <a type="button" class="btn btn-outline-light" href="/users/edit-password">Edit User</a>
              </li>
              <!--------------------->
              
              <li class="nav-item m-1" ...>
              
              {% endif %}
           </ul>
        </div>
    </nav>
</div>
navbar에 Edit User 버튼 생성

 

4. edit-user-password.html 수정

{% include 'layout.html' %}

<div class="container">
    <div class="card">

       <div class="card-header">
            Let's edit your Password!
        </div>

       <div class="card-body">
           {% if msg %}
             <div class="alert alert-danger" role="alert">
               {{msg}}
              </div>
         {% endif %}

            <form method="POST" action="/users/edit-password">
                <div class="form-group col-md-6">
                    <label>Username</label>
                    <input type="text" class="form-control" name="username" value="{{user.get('username')}}" required>
                </div>
                <div class="form-group col-md-6">
                    <label>Password</label>
                    <input type="password" class="form-control" name="password" required>
                </div>
               <div class="form-group col-md-6">
                    <label>New Password</label>
                    <input type="password" class="form-control" name="new_password" required>
                </div>
                <button type="submit" class="btn btn-primary">Edit</button>
            </form>

        </div>
    </div>
</div>
Username input칸에 기본적으로 쿠키에 저장된 username을 넣어준다.
 

 

5. users.py POST API 생성

@router.post("/edit-password", response_class=HTMLResponse)
async def user_password_change(request: Request, password: str = Form(...),
                               new_password: str = Form(...), db: Session = Depends(get_db)):


    user = await get_current_user(request)
    if user is None:
        return RedirectResponse(url="/auth", status_code=status.HTTP_302_FOUND)

    user_data = db.query(models.Users).filter(models.Users.username == user.get("username")).first()

    msg = "Incorrect Username or Password"

    if user_data is not None:
        if verify_password(password, user_data.hashed_password):
            user_data.hashed_password = get_password_hash(new_password)
            db.add(user_data)
            db.flush()
            db.commit()
            msg = "Password Updated Please Login Again"

            response = templates.TemplateResponse("login.html", {"request": request, "msg": msg})
            response.delete_cookie(key="access_token")
            return response

    return templates.TemplateResponse("edit-user-password.html", {"request": request, "msg": msg, "user": user})
verify_password: 패스워드 검사
user_data가 있다면 새로운 패스워드로 업데이트하고 로그인 페이지로 돌아가라(이때 쿠키는 삭제)
user_data가 없다면 새로운 패스워드로 업데이트 하지 말고 다시 패스워드 수정 페이지로 돌아가라

 

6. login.html 수정

{% include 'layout.html' %}

<div class="container">
    <div class="card">
       <!--상단타이틀-->
        <div class="card-header">
            Login
        </div>
        <div class="card-body">

           {% if msg %}
           <!-- Password Updated Please Login Again 조건 추가 -->
           {% if msg == 'Logout Successful' or msg == 'User Successfully created' or msg == 'Password Updated Please Login Again' %}
           <div class="alert alert-success" role="alert">
              {{msg}}
           </div>
           {% else %}
           <div class="alert alert-danger" role="alert">
              {{msg}}
           </div>
           {% endif %}
           {% endif %}

            <form method="POST" action="/auth" ...>
        </div>
       <!--회원가입-->
        <div class="card-footer text-muted" ...>
    </div>
</div>

 

7. 웹으로 비밀번호 변경하기

현재 비밀번호를 잘못 입력하면 에러 메세지가 발생하고 다시 입력해야 한다.

 

비밀번호가 변경되면 다시 로그인 페이지로 돌아오면서 쿠키값은 삭제가 된다.
비밀번호가 변경된 것을 확인하고 싶으면 pgAdmin4에 접속해서 hashed_password가 바뀐 것을 확인한다.
728x90
SMALL
저작자표시 비영리 변경금지 (새창열림)

'Develop > FastAPI' 카테고리의 다른 글

FastAPI 프로젝트 마무리(Render, Elephantsql, 배포하기) - 97  (0) 2023.02.02
FastAPI 프로젝트 git 올리기(git 명령어) - 96  (0) 2023.02.01
FastAPI 프로젝트 진행(코드 정리) - 94  (0) 2023.01.29
FastAPI 프로젝트 진행(회원가입 기능 구현) - 93  (0) 2023.01.29
FastAPI 프로젝트 진행(로그아웃 기능 구현) - 92  (0) 2023.01.29
'Develop/FastAPI' 카테고리의 다른 글
  • FastAPI 프로젝트 마무리(Render, Elephantsql, 배포하기) - 97
  • FastAPI 프로젝트 git 올리기(git 명령어) - 96
  • FastAPI 프로젝트 진행(코드 정리) - 94
  • FastAPI 프로젝트 진행(회원가입 기능 구현) - 93
동석해요
동석해요
공부하고 싶은게 많은, 사소한 IT 지식들 공유
    250x250
  • 동석해요
    개발로 자기계발
    동석해요
  • 전체
    오늘
    어제
    • 분류 전체보기 (226)
      • Develop (126)
        • 기초지식 (12)
        • FastAPI (102)
        • Django (11)
      • Database & Data (62)
        • 기초지식 (16)
        • MySQL (29)
        • PostgreSQL (8)
        • 데이터 분석 (9)
      • 인공지능 (11)
        • PyTorch (9)
      • Cloud (8)
        • AWS (4)
        • GCP (2)
      • 버그처리 (14)
      • 회고 & 일상 (5)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
동석해요
FastAPI 프로젝트 진행(비밀번호 변경, 라우터 추가) - 95
상단으로

티스토리툴바