
💡 개요
FastAPI 프로젝트에 Redis 를 연결한 후 email OTP 인증 기능을 추가하고자 했다.
key : email, value : otp 로 설정을 해놓고 만료시간을 3분으로 설정을 했다.
💡 실행
docker run -p 6379:6379 --name redis -d --rm redis
위 명령어를 통해 docker 로 부터 redis 최신 버전을 다운 받는다.
pip install redis
tests > cache.py
import redis
redis_client = redis.Redis(
host="127.0.0.1", port=6379, db=0, encoding="UTF-8", decode_responses=True
)
host 와 port, db 는 0번째 등등 옵션을 설정해준다.
✔️ OTP 발급
api > user.py
@router.post("/email/otp")
def create_otp_handler(
request: CreateOTPRequest,
_ = Depends(get_access_token),
user_service: UserService = Depends(),
):
otp: int = user_service.create_otp()
redis_client.set(request.email, otp)
redis_client.expire(request.email, 3*60)
return {"otp": otp}
redis_client.set(request.email, otp)
redis_client.expire(request.email, 3*60)
앞서 선언한 redis_client 를 이용해서 set 함수를 통해 key 와 value 를 설정해주고,
expire 함수를 통해 key 와 number * seconds 로 만료시간을 설정해주었다.
✔️ OTP 인증
api > user.py
@router.post("/email/otp/verify")
def verify_otp_handler(
request: VerifyOTPRequest,
access_token: str = Depends(get_access_token),
user_service: UserService = Depends(),
user_repo: UserRepository = Depends()
) -> UserSchema:
otp: str | None = redis_client.get(request.email)
if not otp:
raise HTTPException(status_code=400, detail="Bad Request")
if request.otp != int(otp):
logging.error(
"OTP 불일치 - 요청된 OTP: %s (타입: %s), 저장된 OTP: %s (타입: %s)",
str(request.otp), type(request.otp), str(otp), type(otp)
)
raise HTTPException(
status_code=400,
detail="Bad Request ( otp 불일치 ) " + str(request.otp) + " != " + str(otp)
)
username: str = user_service.decode_jwt(access_token=access_token)
user: User | None = user_repo.get_user_by_username(username=username)
if not user:
raise HTTPException(status_code=404, detail="User Not Found")
user: User = user.update_email(request.email)
return UserSchema.from_orm(user)
1. otp 를 받은 후에 /verify api 에서 email 과 함께 otp 를 입력하면,
2. redis 에 저장된 입력한 email 과 동일한 key 값의 otp 를 가져오고
3. 입력한 otp 와 비교해서 일치하면
4. 입력한 email 을 access token 으로 부터 조회해 접근한 User Table 에 빈 값으로 설정되어있을 email Column 에 업데이트한다.
❌ 타입 불일치 문제
redis 에 저장되어있는 otp 와 입력한 otp 가 동일한데 계속해서 otp 가 동일한데 일치하지 않다는 문제가 발생했다.
integer 타입으로 저장되더라도 redis 에 저장될 때에는 string 타입으로 저장된다는 점을 까먹고 get 으로 가져와서 비교할 때 입력한 int 타입과 불러온 string 타입을 비교하게 되니 숫자가 같아도 계속 불일치 결과가 나왔었다.
int(otp) otp 를 integer 타입으로 강제변환 함으로써 해결해주었다.
'컴퓨터 프로그래밍 > FastAPI' 카테고리의 다른 글
[Alembic] Alembic (0) | 2025.03.15 |
---|---|
[FastAPI] Repository 패턴 및 orm 적용 (0) | 2025.03.15 |
[FastAPI] DB 연결 및 orm 설정 (0) | 2025.03.14 |
[FastAPI] Status_code Error 처리 (0) | 2025.03.14 |
[FastAPI] CRUD (0) | 2025.03.13 |