문제 상황
최근 스프링부트 유지보수를 부탁받아 진행하고 있는 프로젝트에서 특이한 이슈를 만났습니다. 개발 서버에서는 로그인이 잘 되는데, 운영 서버에서는 간헐적으로 로그인이 안 되는 문제였는데요. 더 특이한 점은 iOS에서는 잘 되는데 Android에서만 문제가 발생한다는 점이었습니다.
앱 개발자 분이 보내주신 오류 메시지
{ "status": "FETCH_ERROR", "error": "TypeError: Network request failed" }
처음에는 당연히 클라이언트 쪽 문제일 거라고 생각했습니다. 하지만 앱 개발자분이 "개발 서버와 운영 서버는 엔드포인트만 다르고 호출 방식은 동일하다"고 하심 .. ㅎㅎ
🔍 원인 분석
백엔드 코드를 살펴보니 커스텀 에러 코드를 사용하고 있기 때문에
- MsAP1xx: Business Error
- MsAP4xx: Authentication Error
- MsAP5xx: Server Error
FETCH_ERROR는 RN도 스프링부트도 정의하지 않은 에러 코드였습니다. 이 부분에서 힌트를 얻었는데용 ㅎㅎ
💡 SSL 인증서 체인 확인
운영 서버의 SSL 인증서를 확인해보니:
verify error:num=20:unable to get local issuer certificate
verify error:num=21:unable to verify the first certificate
중간 인증서가 누락되어 있었습니다.
반면 개발 서버는:
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
depth=1 C = US, O = Let's Encrypt, CN = R10
depth=0 CN = dev.e-paps.kr
전체 인증서 체인이 정상적으로 구성되어 있었구요.
🤔 왜 iOS에서는 됐을까?
여기서 재미있는 부분을 발견했습니다. iOS와 Android의 SSL 인증서 체인 검증 방식이 다르더라구요:
- iOS: 비교적 유연한 SSL 체인 검증
- Android: 매우 엄격한 SSL 체인 검증 (중간 인증서 필수)
🛠 해결 방법
Sectigo 중간 인증서를 추가하여 전체 인증서 체인을 완성했습니다:
- 도메인 인증서와 중간 인증서를 하나의 파일로 결합
- 중간 인증서 생성
sudo bash -c 'cat > intermediate.crt << "EOF"
-----BEGIN CERTIFICATE-----
MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
oUmGv38
sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL
l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq
6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY
LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5
yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K
00u/I5sUKUErmgQfky3xxzlIPK1aEn8=
-----END CERTIFICATE-----
EOF'
# 병합
sudo bash -c 'cat e-ensemble_kr.crt intermediate.crt > fullchain.crt'
확인했을 때
아래처럼 ----BEGIN CERTIFICATE ----- 가 두 번 나와야 정상.
# 확인
sudo cat fullchain.crt | grep "BEGIN CERTIFICATE"
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
그리고 본인의 Nginx 설정 파일에
/etc/nginx/sites-available << 이런 곳에
요 설정을 추가해주면 된다.
ssl_certificate /etc/nginx/e-ensemble.kr-ssl/fullchain.crt;
Nginx 파일 수정했으니 -t 해주고 restart 해주고 아시죠?
🎉 결과
- Android에서도 정상적으로 로그인 동작
- SSL 체인 검증 오류 해결
- FETCH_ERROR 해소
📝 배운 점
- FETCH_ERROR가 발생하면 SSL 인증서 체인도 의심해봐야 함
- Android와 iOS의 보안 정책 차이를 이해하는 것이 중요
- 개발/운영 서버의 설정 차이를 꼼꼼히 비교해봐야 함
이런 경험을 통해 플랫폼별 특성과 보안 정책의 중요성을 다시 한번 실감했습니다.....
특히 SSL 인증서 체인이 제대로 구성되어 있지 않으면 Android에서 문제가 발생할 수 있다는 점을 기억해두면 좋을 것 같습니다!
'주절주절.ZIP' 카테고리의 다른 글
[Express] 카카오 소셜로그인에서 겪었던 KOE320 에러.ZIP (0) | 2025.02.11 |
---|---|
[알쓸개잡] 개발자의 구글링 꿀팁.ZIP (4) | 2024.12.28 |