1
0
forked from baron/baron-sso
Files
baron-sso/dev.md
2026-01-06 16:34:05 +09:00

8.6 KiB

개발 문서: SMS 인증 기능 구현

1. 완료된 작업: SMS 인증 전체 플로우 구현 (발송 및 검증)

작업 내역

Backend (Go)

  • Naver SENS API 연동 서비스 구현: (internal/service/sms_service.go)

    • 내용: Naver SENS API를 호출하여 SMS 발송을 요청하는 핵심 모듈을 구현했습니다.
    • 필요 이유: 실제 SMS 메시지를 외부로 발송하기 위한 통신 기능이 필요했습니다.
  • API 엔드포인트 및 핸들러 추가: (cmd/server/main.go, internal/handler/auth_handler.go)

    • 내용: POST /api/v1/auth/sms 엔드포인트를 추가하고, 인증 코드 생성 및 SMS 서비스 호출 로직을 구현했습니다.
    • 필요 이유: 프론트엔드에서 보낸 SMS 발송 요청을 수신하고 처리하기 위한 접점이 필요했습니다.
  • 데이터 모델 정의: (internal/domain/sms_models.go)

    • 내용: API 요청/응답 처리를 위한 Go 데이터 구조(struct)를 정의했습니다.
    • 필요 이유: JSON 데이터를 Go 코드 내에서 타입-세이프(type-safe)하게 다루기 위해 필요했습니다.
  • 입력 값 처리 및 로깅 강화: (internal/handler/auth_handler.go)

    • 내용: 전화번호에서 하이픈(-)을 제거하고, 발송/검증 실패 시 상세 오류를 기록하도록 구현했습니다.
    • 필요 이유: 외부 API의 요구사항을 충족시키고, 운영 중 문제 발생 시 신속하게 원인을 진단하기 위해 필요했습니다.
  • Redis 서비스 구현 및 연동: (internal/service/redis_service.go, internal/handler/auth_handler.go)

    • 내용: Redis 클라이언트 초기화, 인증 코드 저장(StoreVerificationCode), 조회(GetVerificationCode), 삭제(DeleteVerificationCode) 기능을 구현하고, AuthHandlerSendSms 함수에 Redis 저장 로직을 추가했습니다.
    • 필요 이유: 발급된 인증 코드를 임시로 저장하여 사용자가 나중에 입력한 코드와 비교 검증하기 위한 안정적인 저장소가 필요했습니다.
  • 인증 코드 검증 API 엔드포인트 구현: (cmd/server/main.go, internal/handler/auth_handler.go, internal/domain/sms_models.go)

    • 내용: POST /api/v1/auth/verify-sms 엔드포인트를 추가하고, 사용자가 입력한 코드와 Redis에 저장된 코드를 비교 검증하는 VerifySms 함수를 구현했습니다. 관련 데이터 모델도 추가했습니다.
    • 필요 이유: 사용자가 받은 인증 코드를 백엔드에서 확인하고, 인증 성공/실패 여부를 결정하기 위한 API와 로직이 필요했습니다.
  • 인증 성공 시 JWT 발급 로직: (internal/handler/auth_handler.go)

    • 내용: 코드 검증이 성공하면, 해당 사용자에 대한 세션 토큰(JWT)을 생성하여 프론트엔드에 반환합니다.
    • 필요 이유: 사용자가 로그인 상태를 유지하고, 인증이 필요한 다른 API를 호출할 수 있도록 하기 위함입니다.

Frontend (Flutter)

  • SMS 인증 요청 서비스 구현: (lib/core/services/auth_proxy_service.dart)

    • 내용: 백엔드의 SMS 발송 API를 호출하는 sendSms 함수를 추가했습니다.
    • 필요 이유: UI와 백엔드 API 간의 통신을 담당하는 재사용 가능한 서비스 계층을 만들어 코드의 관심사를 분리하기 위해 필요했습니다.
  • 로그인 화면 UI/UX 개선: (lib/features/auth/presentation/login_screen.dart)

    • 내용: 이메일/SMS 인증 탭 UI와 전화번호 입력 필드 및 버튼을 구현했습니다.
    • 필요 이유: 사용자가 SMS 인증 방식을 선택하고 사용할 수 있는 명확한 UI가 필요했습니다.
  • SMS 인증 발송 플로우 로직 구현: (lib/features/auth/presentation/login_screen.dart)

    • 내용: '인증 코드 발송' 버튼 클릭 시 API를 호출하고, 결과에 따라 UI 상태를 동적으로 변경하는 로직을 구현했습니다.
    • 필요 이유: 사용자의 상호작용에 응답하고, 통신 결과에 따라 UI를 동적으로 변경하는 로직이 필요했습니다.
  • 인증 코드 검증 서비스 구현: (lib/core/services/auth_proxy_service.dart)

    • 내용: AuthProxyService에 백엔드의 verify-sms API를 호출하는 함수를 추가했습니다.
    • 필요 이유: 인증 코드 검증을 위해 백엔드와 통신하는 서비스 로직이 필요했습니다.
  • 인증 코드 검증 플로우 로직 구현: (lib/features/auth/presentation/login_screen.dart)

    • 내용: '코드 확인' 버튼 클릭 시, 입력된 코드와 전화번호를 백엔드로 보내 검증을 요청하는 로직을 구현했습니다.
    • 필요 이유: 사용자의 코드 제출 액션에 응답하는 로직이 필요했습니다.
  • 인증 결과 처리: (lib/features/auth/presentation/login_screen.dart)

    • 내용: 검증 성공 시 JWT를 콘솔에 출력하고 성공 다이얼로그를 표시합니다. (JWT 저장 및 대시보드 이동은 TODO 상태)
    • 필요 이유: 인증 결과에 따라 사용자에게 적절한 피드백(화면 전환 또는 오류 안내)을 제공해야 합니다.

전체 인증 플로우: 시퀀스 다이어그램

sequenceDiagram
    participant 사용자
    participant Flutter as Flutter (Frontend)
    participant Go as Go (Backend)
    participant NaverSMS as Naver SMS API

    Note over 사용자, NaverSMS: 1. 인증 코드 발송 단계
    사용자->>Flutter: 전화번호 입력 후 '인증 코드 발송' 요청
    Flutter->>Go: POST /api/v1/auth/sms
    Go->>Go: 6자리 인증 코드 생성 & 임시 저장 (Redis)
    Go->>NaverSMS: SMS 발송 요청 (인증 코드 포함)
    NaverSMS-->>사용자: [SMS] 인증번호 메시지 수신
    NaverSMS-->>Go: 발송 요청 결과 응답
    Go-->>Flutter: 처리 결과 응답 (성공)
    Flutter->>사용자: UI 업데이트 (인증번호 입력창 표시)

    Note over 사용자, Go: 2. 인증 코드 검증 단계
    사용자->>Flutter: 수신한 인증 코드 입력 후 '코드 확인' 요청
    Flutter->>Go: POST /api/v1/auth/verify-sms (전화번호, 입력 코드)
    Go->>Go: 임시 저장된 코드와 비교 및 검증 (Redis)
    
    alt 인증 성공
        Go->>Go: JWT(세션 토큰) 생성
        Go-->>Flutter: 인증 성공 응답 (JWT 포함)
        Flutter->>Flutter: JWT 수신 및 처리 (저장 및 대시보드 이동 예정)
        Flutter->>사용자: 성공 메시지 표시
    else 인증 실패
        Go-->>Flutter: 인증 실패 응답
        Flutter->>사용자: 오류 메시지 표시
    end


2. 발생 이슈 및 해결 과정 (통합)

  1. 발신자 번호 미인증 오류

    • 이슈: SENS API에서 'from' is not an authenticated tel number 오류 반환.
    • 해결: 네이버 클라우드 플랫폼 콘솔에서 SMS 발신 번호를 등록하고 인증 절차를 완료한 후, .env 파일의 NAVER_SENDER_PHONE_NUMBER 값을 인증된 번호로 수정.
  2. 환경 변수 누락으로 인한 API URL 생성 실패

    • 이슈: 백엔드 컨테이너가 NAVER_CLOUD_SERVICE_ID 환경 변수를 읽지 못해 URL not found 오류 발생.
    • 해결: docker-compose.yamlbackend 서비스에 env_file: [".env"] 설정을 추가하여 컨테이너가 .env 파일의 모든 변수를 로드하도록 수정.
  3. 전화번호 형식 불일치 오류

    • 이슈: SENS API에서 phone number format excluding dash(-) 오류 반환.
    • 해결: 백엔드 AuthHandler에서 SENS API로 전화번호를 전달하기 전, strings.ReplaceAll 함수를 사용하여 하이픈(-)을 모두 제거하는 로직 추가.
  4. Redis 연결 실패 오류

    • 이슈: 백엔드 컨테이너가 Redis에 접속하지 못하고 Failed to connect to Redis: dial tcp [::1]:6379: connect: connection refused 오류 발생.
    • 해결: 프로젝트 루트의 .env 파일에 REDIS_ADDR=redis:6379를 추가하고, docker-compose up -d --force-recreate 명령을 통해 컨테이너를 강제로 재생성하여 변경된 환경 변수를 적용.
  5. Go 백엔드 빌드 실패 (JWT 라이브러리 import 누락)

    • 이슈: Docker 이미지 빌드 중 undefined: jwt 컴파일 오류 발생.
    • 해결: backend/internal/handler/auth_handler.go 파일에 "github.com/golang-jwt/jwt/v4" import 구문을 추가하여 해결.