Vercel의 도메인 서비스를 이용하여 구현한 AI문의창이 있는 페이지에서 결과 화면에 다음과 같은 에러 메시지가 출력되었다.

'오류 발생: API 호출 중 최대 재시도 횟수 초과: API 요청 실패 (HTTP 403): {"error":{"code":403,"message":"Your API key was reported as leaked. Please use another API key.","status":"PERMISSION_DENIED"}}'
이는 API키가 유출되었다고 알려주는 메시지였습니다. 위의 화면 html 소스에 API Key가 있는 상태에서 이를 github에 올렸고, 이를 Vercel을 통해 배포하였기 때문이었습니다.

이런 경우 API_KEY는 어떻게 해야할까? 암호화? 그럼 그 암호화에 사용한 키는 또 어떻게 관리하지???
이런 걱정을 gemini에 문의를 하니 Vercel 의 환경변수에 API_KEY를 넣고 사용하는 방법을 안내해 주었다.
1. 먼저 기존에 사용하던 키가 유출되었으니 API_KEY를 다시 발급받는다.

유출된 키가 있음을 확인했고, 다시 키를 발급받는다.
2. Vercel에서 API_KEY를 등록한다.
Vercel 의 위쪽 탭에서 'Settings > Environment Variables' 를 선택하여 Key를 입력하고 
3. Vercel Serverless Function 구현 (프록시 역할)
기존 소스코드 구조에 다음과 같이 api폴더에 gemini-proxy.js 를 만들어서 넣어준다.


// Serverless Function (Node.js 환경)
// 1. Vercel 환경 변수에서 API 키를 안전하게 불러옵니다.
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
// 2. 모델 엔드포인트는 고정된 주소를 사용합니다.
const MODEL_NAME = "gemini-2.5-flash-preview-09-2025";
const API_URL = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL_NAME}:generateContent?key=${GEMINI_API_KEY}`;
export default async function handler(req, res) {
// 3. POST 요청만 허용합니다.
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method Not Allowed' });
}
try {
// 4. 클라이언트가 보낸 JSON 페이로드를 가져옵니다.
const payload = req.body;
// 5. Gemini API에 요청을 중계합니다. (API 키는 서버에만 존재)
const geminiResponse = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
// 6. Gemini 응답의 상태 코드를 그대로 클라이언트에게 전달합니다.
const data = await geminiResponse.json();
if (geminiResponse.ok) {
res.status(200).json(data);
} else {
// Gemini API에서 발생한 오류를 클라이언트에게 전달합니다.
res.status(geminiResponse.status).json(data);
}
} catch (error) {
console.error("Proxy Error:", error);
res.status(500).json({ error: 'Internal Server Error during API call.', details: error.message });
}
}
이제 기존 html 소스코드에서 API_KEY, API_URL을 삭제하고, Vercel의 URL을 넣는다.
<script>
// API 설정 (Canvas 환경에서 __initial_auth_token이 제공되지 않으므로, API Key를 사용합니다.)
// Canvas 환경에서 자동으로 API 키가 주입되므로, 빈 문자열로 유지합니다.
const API_KEY = "XXXXXXXXXXXXXXXXXXXXXXX";
const MODEL_NAME = "gemini-2.5-flash-preview-09-2025";
const API_URL = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL_NAME}:generateContent?key=${API_KEY}`;
// DOM 요소
<script>
// API 설정 (Canvas 환경에서 __initial_auth_token이 제공되지 않으므로, API Key를 사용합니다.)
// Canvas 환경에서 자동으로 API 키가 주입되므로, 빈 문자열로 유지합니다.
// ✅ 추가할 코드 (프록시 엔드포인트)
const PROXY_URL = '/api/gemini-proxy';
// DOM 요소
위와 같이 코드 수정 후 Vercel 에서 Redeploy가 되면 적용이 완료된다.
'python' 카테고리의 다른 글
| Vercel을 이용한 웹페이지 개발 (0) | 2025.12.05 |
|---|---|
| JIRA Automation: 파이썬 스크립트로 시작하는 이슈 관리 효율화 (0) | 2025.05.12 |
| python, LSTM을 활용한 주식 가격 예측 (3) | 2024.08.30 |
| pyinstaller로 배포할 exe에 필요한 파일들 모두 포함시키는 방법 (0) | 2024.06.13 |
| python 주식 가격 알림 메일 보내기 (59) | 2023.10.19 |