Skip to content

Feat/auth#25

Open
myoungjugo wants to merge 21 commits into
developfrom
feature/auth
Open

Feat/auth#25
myoungjugo wants to merge 21 commits into
developfrom
feature/auth

Conversation

@myoungjugo

@myoungjugo myoungjugo commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

##작업 개요##
회원가입, 로그인, 비밀번호 재설정 및 토큰 관리 로직을 완성하고, 보안 취약점 개선 및 API 명세서 규격을 준수하도록 리팩토링을 진행했습니다.

##주요 변경 사항##

  1. 인증 및 계정 관리 로직 완성
    이메일 인증 시스템: 회원가입 시 인증 메일을 발송하며, 인증 완료 시 사용자에게 제공할 전용 HTML 성공 페이지를 HTMLResponse로 반환하도록 구현했습니다.

비밀번호 재설정 흐름 개선:

이메일 링크의 목적지를 백엔드 API가 아닌 **프론트엔드 UI 주소(3000번 포트)**로 수정하여 405 Method Not Allowed 에러를 해결했습니다.

재설정 완료 시 보안을 위해 평문 비밀번호 대신 성공 메시지 혹은 명세서 규격에 따른 응답을 반환합니다.

  1. 토큰 시스템 (JWT) 고도화
    Token Scope 도입: Access 토큰과 Refresh 토큰의 용도를 scope 페이로드로 구분하여 보안을 강화했습니다.

Refresh 로직 수정: 기존 리프레시 토큰 유효성 검사 후, 새로운 액세스 토큰을 발급하는 로직을 명세서 규격에 맞춰 정비했습니다.

  1. 보안 및 유효성 검사 강화
    공통 비밀번호 검증 로직 (validate_password):

Pydantic 스키마 내에 중복되던 검증 로직을 공통 함수로 분리했습니다.

규칙: 8자 이상, 영문 대/소문자, 숫자, 특수문자 각각 1개 이상 포함 필수.

회원가입(SignUpRequest) 및 비밀번호 재설정(PasswordResetConfirm)에 동일하게 적용했습니다.

보안 전송: 패킷 탈취 방지를 위해 민감 정보(비밀번호 등)는 HTTPS 환경(실운영) 전송을 전제로 설계되었습니다.

  1. 응답 모델 및 명세서 준수 및 수정
    명세서에 정의된 각 엔드포인트의 응답 모델(Pydantic)을 최신화했습니다.

TokenRefreshResponse 등 누락되었던 필드(access_token)를 추가하여 프론트엔드와의 통신 규격을 맞췄습니다.

또한 password/reset/{user_token} 의 응답을 비밀번호 평문으로 기재했었는데, 이는 보안상 문제가 있어 성공 메시지만 반환하는 것으로 수정했습니다.

##변경된 주요 파일##
app/services/auth_service.py: 비즈니스 로직(로그인, 재설정, 토큰 갱신) 전면 수정

app/schemas/auth_schemas.py: 비밀번호 공통 검증 함수 도입 및 모델 정비

app/services/email_service.py: 메일 링크 주소(프론트엔드로) 수정

app/routers/auth_router.py: 엔드포인트 및 의존성 주입 로직 최적화

##테스트 결과##

[hoppscotch에 올려두었습니다!]

Signup & Verify: 이메일 수신 및 인증 완료 페이지 렌더링 확인 완료.

Signin & Refresh: JWT 발급 및 리프레시 토큰을 이용한 액세스 토큰 재발급 확인 완료.

Password Reset:

메일 링크 클릭 시 프론트엔드(3000) 연결 확인.

POST 요청을 통한 비밀번호 변경 및 변경된 비번으로 로그인 성공 확인.

Validation: 8자 미만 또는 특수문자 미포함 시 422 Unprocessable Entity 에러 반환 확인.

비밀번호 재설정 시 GET 요청은 프론트엔드에서 UI를 렌더링하는 용도이므로 백엔드 라우터에서는 제외했습니다. 대신 메일 링크 주소를 프론트엔드 서버 주소(임시, localhost:3000)로 맞췄으니 확인 부탁드립니다!

- venv를 써서 작업했기에 에디터 및 OS 설정과 파이썬 가상환경 관련한 내용을 추가
- password 설정 모델을 signup안으로 넣음
- pydantic 모델을 모음
- docstring 추가
- 데이터베이스 접근 위한 함수 추가
- 하나의 코드 파일에서 db접근까지 하는 것을 방지하기 위함
- SQLAlchemy 메서드를 주로 사용함
- docstring로 타입명시

[추가한 함수들]
- get_db
- get_user_by_email
- get_auth_user_by_id
- create_user
- create_auth_user
- commit
- refresh_user_stat
- 사용자 등록, 이메일 인증, 로그인 흐름 구현
- 비밀번호 해싱은 passlib(bcrypt)사용
- 토큰 생성은 JWT(HS256)사용
- SECRET_KEY는 환경 변수에서 읽어옴

[함수]
- register_new_user
  - 사용자/인증 사용자 생성
  - 비밀번호 해싱
  - 인증 토큰 생성
  - 인증 이메일 전송
- verify_email
  - 토큰 디코딩
  - 계정 인증 완료 표시
- sign_in
  - 자격 증명 유효성 검사
  - 액세스 토큰 반환
- 예전에 수많은 함수 포함 -> 통신 및 응답 기능만
- docstring으로 타입 명시

[엔드포인트 안 함수]
- signup
  회원가입 api엔드포인트
  json 요청 바디 데이터를 받고 db 세션 주입
  pydantic 사용해 해당 타입으로 받고
  register_new_user를 수행하고 기다림

- verify_email
  이메일 인증 토큰을 검증해 계정을 활성화
  사용자가 메일로 받은 링크 클릭 시 호출되며, 토큰이 유효하면 AuthUser의 인증 상태를 True로 변경하고 통계 뷰 갱신

- signin
  사용자 로그인을 처리하고 액세스 토큰 발급 이메일과 비밀번호 검증, 모든 조건(계정 존재, 비밀번호 일치, 이메일 인증 완료)이 충족되면 향후 API 요청에 사용할 JWT 액세스 토큰 반환
- 상단 이메일 발송 메소드 import(app.services.email_service
- utcnow가 더 이상 쓰이지 않기에
datetime.now(datetime.timezone.utc)로 수정
- timezone을 쓰기 위해 임포트
- 그 외 오타 수정
pydantic 스키마 정의
db조회 함수들(반복적으로 쓰이던 db함수를 여기서 정의)
라우터 함수만 남김
서비스 함수 정리
- get_user_jandi_data
- generate_signed_url
- get_jandi_widget_html
- 기존에 있던 get_jandi_data를 db함수로 뺌
- 라우터 함수 9개 엔드포인트 구현
추가된 엔드포인트에 맞는 응답/요청 모델 작성
trend에서 응답 모델을 원하는데 request라고 써둔 것을 응답으로 알맞게 고침
- 새로 추가된 엔드포인트에 맞는 서비스 함수들 작성
- password/reset/{user} api 명세서에서 응답으로 바뀐 새 비밀번호를 리턴하는 게 있었음
-> 바뀐 새 비밀번호를 평문으로 제시할 경우 패킷 공격에 취약하므로 내부적으로만 업데이트, 응답으로는 성공적으로 변경되었음만 알림
- auth에서 인증 메일 보내는 함수 구현
- 기존 html부분을 템플릿으로 넘기고 이메일 인증/비밀번호 재설정 이렇게 기능별로 나눔
이메일로 유저에게 보여지는 임의 html 페이지를 email_templates에 모아둠
- TokenRefreshResponse 응답모델 추가, refresh_token과 새 access_token까지 리턴하도록 수정
- 인증메일 클릭 시 html 페이지 안보이던것 해결, 인증 완료 시 html 페이지도 임의로 email_template에 만듦
- 이메일 보내는 함수에 프론트엔드 주소가 정해지지 않아 404가 뜨던 문제를, 주소가 정해질 때까지 임시로 localhost:8000으로 설정

- 현재 회원가입, 로그인, 토큰 관리 로직은 테스트 완료했고 비밀번호 재설정 로직 테스트 진행중
*테스트 중 명세서에 잘못 기입한 부분이 있어 수정하였습니다!*

*비밀번호 재설정 로직 테스트까지 완료하였습니다. 테스트 요청은 hoppscotch에 올려뒀습니다!*

- GET password/reset/{user}는 프론트에서 개발, 즉 POST password/reset/request 시 이메일로 간 링크를 프론트로 보내줘야 하기 때문에 localhost:8000 -> localhost:3000(임시)로 바꿈

- 비밀번호 검증(8자이상, 대소문자, 숫자, 특수문자 포함) 로직이 회원가입, 비밀번호 재설정 두 가지 경우 모두 쓰이기 때문에 따로 validate_password 함수로 빼서 auth_schemas 상단에 정의함.
@myoungjugo myoungjugo changed the title Feature/auth Feat/auth May 14, 2026
@myoungjugo

Copy link
Copy Markdown
Contributor Author

gitignore 충돌 해결했습니다
develop 브랜치와 머지 가능할 듯 합니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant