프론트엔드 기초 다시 쌓기 챌린지 18일차.
Part 2 "환경변수·시크릿·보안"의 세 번째 수업.Day 16에서 NEXTPUBLIC 규칙을, Day 17에서 .env 관리법을 배웠다면,
오늘은 API 키를 체계적으로 관리하는 실전 패턴을 배웠다.
납품업체에서 카드를 두 장 줬다.
🔓 주문 카드 (공개 키 / Publishable Key)
- 직원 누구나 써도 됨
- 잃어버려도 큰 문제 없음 (주문만 가능하니까)
🔒 정산 카드 (시크릿 키 / Secret Key)
- 사장님만 갖고 있어야 함
- 잃어버리면 누가 돈을 빼갈 수 있음!
API 키도 똑같다. 대부분의 서비스가 공개 키와 시크릿 키를 한 쌍으로 준다.
# Stripe (결제)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_abc123 # 🔓 공개 키
STRIPE_SECRET_KEY=sk_live_xyz789 # 🔒 시크릿 키
# 카페24 API
NEXT_PUBLIC_CAFE24_CLIENT_ID=app_abc123 # 🔓 클라이언트 ID
CAFE24_CLIENT_SECRET=secret_xyz789 # 🔒 클라이언트 시크릿
# Google Maps
NEXT_PUBLIC_GOOGLE_MAPS_KEY=AIza_abc123 # 🔓 브라우저에서 지도 띄울 때
GOOGLE_MAPS_SERVER_KEY=AIza_xyz789 # 🔒 서버에서 좌표 변환할 때
🔓 공개 가능 (이런 이름이면 공개 OK)
- publishable, public, client_id
- pk_ 로 시작
🔒 비밀 (이런 이름이면 비밀!)
- secret, private, server
- sk_ 로 시작
판단이 안 되면 시크릿으로 취급한다. 안전한 쪽으로 가는 게 정답.
거의 모든 API 서비스가 테스트 키와 라이브 키를 따로 준다:
테스트 키 (test/sandbox):
- 실제 결제 안 됨, 개발할 때 사용
- sk_test_..., pk_test_...
라이브 키 (live/production):
- 실제 결제 됨, 실서비스에서 사용
- sk_live_..., pk_live_...
# .env.development (개발용 - 테스트 키)
STRIPE_SECRET_KEY=sk_test_개발용키
# .env.production (실서비스 - 라이브 키)
STRIPE_SECRET_KEY=sk_live_실제키
인증 에러가 나는 게 아니라 정상 작동해버리는 게 문제다!
테스트 키로 결제 → 가짜 결제 (돈 안 빠져나감) ✅
라이브 키로 결제 → 진짜 결제 (돈이 빠져나감!) 😱
개발하면서 테스트 결제를 10번 했는데 라이브 키였다면?
진짜로 10번 결제된 것이다. 고객 카드에서 실제로 돈이 빠져나간다.
레스토랑 비유: 연습 주문이라고 생각하고 10번 주문했는데,
진짜 납품처(라이브 키)로 보내서 실제 재료가 10번 배달되고 비용이 청구된 것.
그래서 .env.development에는 반드시 테스트 키를,
.env.production에만 라이브 키를 넣어야 한다.
# ❌ 나쁜 예: 뭐가 뭔지 모름
KEY1=abc123
KEY2=xyz789
# ✅ 좋은 예: 이름만 봐도 알 수 있음
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_abc123
STRIPE_SECRET_KEY=sk_live_xyz789
# .env.development → 테스트 키 # .env.production → 라이브 키3. 키에 권한 제한 걸기
API 서비스 대시보드에서 키의 권한을 최소한으로 설정한다.
❌ 모든 권한이 열린 키 (읽기, 쓰기, 삭제, 관리자 전부) ✅ 필요한 권한만 열린 키 (읽기 전용 등)레스토랑 비유: 직원 카드에 "식재료 주문만 가능, 한도 50만 원" 제한을 거는 것.
4. 키를 주기적으로 교체 (Key Rotation)
3~6개월마다: 1. 새 키 발급 2. .env, GitHub Secrets, 서버에 새 키 적용 3. 정상 작동 확인 4. 이전 키 삭제/무효화키가 언제 유출됐는지 모를 수 있으니 주기적으로 바꾸면 피해 기간을 줄일 수 있다.
5. 키를 코드에 절대 하드코딩하지 않기
// ❌ 절대 이렇게 하면 안 됨! const stripe = new Stripe("sk_live_xyz789_진짜키"); // ❌ 주석에도 쓰면 안 됨! // API 키: sk_live_xyz789 ← git에 올라감! // ✅ 항상 환경변수에서 가져오기 const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
📄 .env.example 실전 가이드
좋은 .env.example 작성법
# .env.example # 이 파일을 .env.local로 복사한 뒤 실제 값을 입력하세요. # cp .env.example .env.local # ============================================ # 🔓 공개 키 (NEXT_PUBLIC_) # ============================================ # Stripe 결제 (https://dashboard.stripe.com/apikeys) NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_여기에입력 # Google Maps (https://console.cloud.google.com) NEXT_PUBLIC_GOOGLE_MAPS_KEY=여기에입력 # 사이트 기본 설정 NEXT_PUBLIC_SITE_URL=http://localhost:4040 # ============================================ # 🔒 시크릿 키 (서버 전용) # ============================================ # Stripe 결제 시크릿 STRIPE_SECRET_KEY=sk_test_여기에입력 # 데이터베이스 DATABASE_URL=postgresql://user:password@localhost:5432/mydb # 카페24 API CAFE24_CLIENT_ID=여기에입력 CAFE24_CLIENT_SECRET=여기에입력 # ============================================ # 📝 참고사항 # ============================================ # - 개발 시에는 test 키 사용 (sk_test_, pk_test_) # - 프로덕션 키는 팀 리더에게 문의 # - 절대 이 파일에 실제 키를 입력하지 마세요!포인트 정리
✅ 공개 키와 시크릿 키를 구분해서 정리 ✅ 각 키를 어디서 발급받는지 URL 표시 ✅ 설명 주석 달기 ✅ 복사 명령어 안내 ✅ "여기에입력" 같은 플레이스홀더 사용 ❌ 실제 키 값을 절대 넣지 않기!
🔄 키 하나의 일생: 전체 흐름
[1. 키 발급] API 서비스 대시보드에서 테스트 키 + 라이브 키 한 쌍 발급 [2. 키 저장 - 3곳에] 내 컴퓨터: .env.local에 테스트 키 서버: .env에 라이브 키 CI/CD: GitHub Secrets에 라이브 키 [3. 키 사용] 공개 키 → NEXT_PUBLIC_ 붙여서 브라우저에서 사용 시크릿 키 → 서버 사이드 코드에서만 사용 [4. 키 가이드] .env.example에 "이런 키가 필요해요" 기록 → git에 올려서 팀 공유 [5. 키 교체 (3~6개월마다)] 새 키 발급 → 3곳 업데이트 → 이전 키 삭제 [6. 키 유출 시] 키 즉시 무효화 → 새 키 발급 → 3곳 업데이트
🔗 Day 16~18 연결: 환경변수 3일 총정리
Day 16: NEXT_PUBLIC_ 붙으면 브라우저 노출, 안 붙으면 서버 전용 → 빌드할 때 JS 파일에 값이 직접 박히기 때문 Day 17: 환경별 .env 파일 + 유출 시 키 무효화가 1순위 → .env.local > .env.development/.production > .env Day 18: 공개 키 vs 시크릿 키 구분 + 키 관리 5가지 원칙 → 테스트 키와 라이브 키 분리, 하드코딩 절대 금지
🍳 레스토랑 비유 업데이트
| 레스토랑 | 서버 |
|---|---|
| 주문 카드 (직원 누구나 사용) | 공개 키 (Publishable Key) |
| 정산 카드 (사장님만 보관) | 시크릿 키 (Secret Key) |
| 연습용 납품처 | 테스트 키 (sktest, pktest) |
| 진짜 납품처 | 라이브 키 (sklive, pklive) |
| 카드에 "주문용" 라벨 | 키 이름에 용도 명시 |
| 카드 한도 제한 | 키 권한 최소한으로 설정 |
| 자물쇠 주기적 교체 | Key Rotation (3~6개월) |
| 카드 번호를 메뉴판에 적음 | 키를 코드에 하드코딩 = 대참사 |
Q1. pk_live_abc123과 sk_live_xyz789 각각 어디서 사용?
→ 정답: pk(공개 키)는 NEXTPUBLIC 붙여서 브라우저에서 사용. sk(시크릿 키)는 서버 사이드 코드에서만 사용.
Q2. 개발할 때 라이브 키를 쓰면?
→ 정답: 인증 에러가 나는 게 아니라 정상 작동해버린다. 테스트 결제가 진짜 결제가 되어 실제로 돈이 빠져나감.
Q3. 새 팀원이 빠르게 프로젝트 세팅하려면?
→ 정답: .env.example이 잘 정리되어 있어야 한다. 어떤 키가 필요한지, 어디서 발급받는지, 공개/시크릿 구분까지 적혀있으면 빠르게 세팅 가능.
환경변수에 대해 3일 연속 배우고 있는데, 매일 "이건 몰랐다" 하는 게 나온다.
오늘 가장 충격이었던 건 라이브 키를 개발에 쓰면 에러가 나는 게 아니라 진짜 작동해버린다는 것.
"테스트 결제가 진짜 결제가 된다"는 말에 소름이 돋았다.
.env.development에 테스트 키, .env.production에 라이브 키를 분리하는 게
단순한 정리가 아니라 사고 예방이었다.
그리고 .env.example 작성법을 배우면서,
"코드만 잘 짜면 되는 게 아니라 팀이 같이 쓸 수 있게 정리하는 것도 개발"이라는 걸 느꼈다.
Day 19: 프론트엔드 보안 기본기 (XSS, CSRF 개념)
해커가 우리 사이트를 어떻게 공격하는지, 어떻게 막는지 배운다.
#프론트엔드 #API키 #환경변수 #보안 #env #2년차개발자 #기초다시쌓기