본문 바로가기
python

Vercel에서 API Key 관리

by sanglim 2025. 12. 5.
반응형

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가 되면 적용이 완료된다.

반응형