Skt 그리닷 project To Do List 01/22

이성원·2024년 1월 22일
0

오늘 작업
비동기 회원가입 구현, db연동 test

회원가입 구현

회원가입 구현할 register.py 와 비밀번호를 해싱해줄 utils.py를 생성헀다

register.py

from fastapi import FastAPI, HTTPException
from .models import Member, RoleEnum, StatusEnum, GradeEnum
from .utils import hash_password
from pydantic import BaseModel
from datetime import datetime
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from config import ASYNC_DATABASE_URI

# Pydantic 모델 정의 - 사용자 입력을 검증하기 위함
class RegisterRequest(BaseModel):
    email: str
    nickname: str
    password: str

app = FastAPI()
# 비동기 데이터베이스 엔진 생성
engine = create_async_engine(ASYNC_DATABASE_URI)
# 비동기 세션 생성자
AsyncSessionLocal = sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)

@app.post('/register')
async def register_member(request: RegisterRequest):
    # 입력 데이터 검증
    email = request.email
    nickname = request.nickname
    password = request.password

    if not email or not nickname or not password:
        raise HTTPException(status_code=400, detail="모든 필드를 입력해야 합니다.")

    # 비밀번호 해싱
    hashed_pwd = hash_password(password)

    # 새 회원 객체 생성
    new_member = Member(
        email=email,
        nickname=nickname,
        password=hashed_pwd,
        role=RoleEnum.MEMBER,  # 기본 역할 설정
        status=StatusEnum.ACTIVATE,  # 기본 상태 설정
        grade=GradeEnum.FREE,  # 기본 등급 설정
        register_at=datetime.now()  # 현재 시간 설정
    )

    async with AsyncSessionLocal() as session:
        async with session.begin():
            try:
                session.add(new_member)
                # 비동기 커밋
                await session.commit()
            except Exception as e:
                await session.rollback()
                raise HTTPException(status_code=500, detail=f"회원가입 실패: {e}")

    return {"message": "회원가입이 완료되었습니다."}

처음엔 아래처럼 생성했는데 비동기로 구현을 하는게 맞다고 생각이 들어서 수정했다.

engine = create_engine(DATABASE_URI)
Session = sessionmaker(bind=engine)

    session = Session()
    try:
        session.add(new_member)
        session.commit()
    except Exception as e:
        session.rollback()
        raise HTTPException(status_code=500, detail=f"회원가입 실패: {e}")
    finally:
        session.close()

utils.py

import bcrypt
#비밀번호 해싱
def hash_password(password):
    return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())

해싱은 bcrypt 해싱을 사용했다.

BCrypt는 패스워드를 해싱할 때 내부적으로 랜덤 한 salt를 생성하기 때문에 같은 문자열에 대해서 매번 다른 해싱 결과를 반환한다

이처럼 salt가 통합된 형식으로 인해 레인보 테이블(rainbow table) 공격을 방지할 수 있으며, 반복 횟수를 늘려서 연산 속도를 늦출 수 있기 때문에 연산 능력이 증가하더라도 브루트 포스(brute force) 검색 공격에 대비할 수 있다.

db 연동 test

profile
개발자

0개의 댓글

관련 채용 정보