π ν΄λΌμ΄μΈνΈ μ½λμ λ―Όκ°ν API ν€ μ§μ λ ΈμΆ: 보μ μΉ¨ν΄μ μλΉμ€ λ¨μ©μ μ§λ¦κΈΈ
Summary
ν΄λΌμ΄μΈνΈ μ¬μ΄λ μ½λμ API ν€λ λ―Όκ°ν μ€μ μ 보λ₯Ό μ§μ ν¬ν¨νλ κ²μ μ¬κ°ν 보μ μ·¨μ½μ μ λλ€. 곡격μκ° μ΄λ₯Ό νμ·¨νμ¬ μλΉμ€ λ¨μ©, λ°μ΄ν° μ μΆ λ±μ λ¬Έμ κ° λ°μν μ μμ΅λλ€. κ°μ₯ μμ ν λ°©λ²μ λ°±μλ νλ‘μ μλ²λ₯Ό ν΅ν΄ ν€λ₯Ό κ΄λ¦¬νλ κ²μ΄λ©°, ν΄λΌμ΄μΈνΈ λ²λ€μ λ ΈμΆλ μλ°μ μλ κ³΅κ° ν€μ κ²½μ°μλ νκ²½ λ³μλ₯Ό μ¬μ©νκ³ ν΄λΉ μλΉμ€μ 보μ μ€μ μ νμ©νμ¬ μ€μ©μ λ°©μ§ν΄μΌ ν©λλ€.
Why Wrong?
ν΄λΌμ΄μΈνΈ μ¬μ΄λ μ½λ(JavaScript λ²λ€, HTML λ±)λ μ¬μ©μμ λΈλΌμ°μ μμ μ€νλλ©°, κ°λ°μ λꡬλ₯Ό ν΅ν΄ λꡬλ μ½κ² μ κ·Όνμ¬ λ΄μ©μ λΆμνκ³ λμ»΄νμΌν μ μμ΅λλ€. μ¬κΈ°μ API ν€λ μΈμ¦ ν ν°, λ―Όκ°ν μ€μ κ° λ±μ μ§μ λ ΈμΆνλ κ²μ λ€μκ³Ό κ°μ μ¬κ°ν 보μ μ·¨μ½μ μ μΌκΈ°ν©λλ€.
- 보μ μ·¨μ½μ : μ μμ μΈ μ¬μ©μκ° μ½λλ₯Ό λΆμνμ¬ λ―Όκ°ν API ν€λ₯Ό νμ·¨ν μ μμ΅λλ€. μ΄λ ν΄λΉ API μλΉμ€μ 무λ¨μΌλ‘ μ κ·Όνκ±°λ μ€μ©ν μ μλ ν΅λ‘κ° λ©λλ€.
- μλΉμ€ λ¨μ© λ° λΉμ© λ°μ: νμ·¨λ API ν€λ μ£Όλ‘ μΈλΆ μλΉμ€(μ§λ API, κ²°μ API, AI API λ±)μ ν λΉλμ μλͺ¨νκ±°λ, 곡격μκ° μ체μ μΌλ‘ κ°λ°ν μ μ± μλΉμ€μ μ°λνμ¬ κΈμ μ νΌν΄λ₯Ό μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, μ§λ API ν€κ° λ ΈμΆλλ©΄ 무λ¨μΌλ‘ κ³Όλν μμ²μ λ°μμμΌ λΆνμν μ¬μ©λ£λ₯Ό μ²κ΅¬λΉν μ μμ΅λλ€.
- λ°μ΄ν° μ μΆ μν: λ―Όκ°ν API ν€κ° λ°μ΄ν°λ² μ΄μ€λ λ€λ₯Έ λ°±μλ μλΉμ€μ μ°λλμ΄ μλ€λ©΄, ν€ νμ·¨λ κ³§ μ€μν λ°μ΄ν° μ μΆμ ν΅λ‘κ° λ μ μμ΅λλ€.
- μ μ§λ³΄μ μ΄λ €μ: κ°λ°, ν μ€νΈ, νλ‘λμ νκ²½λ§λ€ λ€λ₯Έ ν€λ₯Ό κ΄λ¦¬νκΈ° μ΄λ ΅κ³ , ν€ λ³κ²½ μλ§λ€ μ½λ μ 체λ₯Ό μ¬λ°°ν¬ν΄μΌ νλ λ²κ±°λ‘μμ΄ λ°μν©λλ€.
How to Fix?
λ―Όκ°ν API ν€λ μ λ ν΄λΌμ΄μΈνΈ λ²λ€μ μ§μ ν¬ν¨ν΄μλ μ λ©λλ€. λ€μ λ°©λ²μ ν΅ν΄ μμ νκ² κ΄λ¦¬ν΄μΌ ν©λλ€.
-
λ°±μλ νλ‘μ μλ² νμ© (κ°μ₯ κΆμ₯): κ°μ₯ κ°λ ₯ν 보μ λ°©λ²μ λλ€. λ―Όκ°ν API ν€κ° νμν λͺ¨λ μμ²μ νλ°νΈμλμμ μ§μ μΈλΆ API μλΉμ€λ‘ 보λ΄λ λμ , κ°λ°μκ° ν΅μ νλ λ°±μλ μλ²(νλ‘μ)λ₯Ό κ±°μ³ λ°±μλμμ API ν€λ₯Ό μ¬μ©νμ¬ μ€μ μΈλΆ API μλΉμ€μ μμ²μ 보λ λλ€. λ°±μλ μλ²λ API ν€λ₯Ό νκ²½ λ³μλ‘ μμ νκ² κ΄λ¦¬νλ©°, ν΄λΌμ΄μΈνΈλ μ€μ§ λ°±μλ νλ‘μ μλ²μ ν΅μ ν©λλ€. μ΄ λ°©μμ API ν€κ° ν΄λΌμ΄μΈνΈμκ² μ ν λ ΈμΆλμ§ μλλ‘ ν©λλ€.
-
νκ²½ λ³μ μ¬μ© (λΉλ μ μ£Όμ , κ³΅κ° ν€μ νν¨): μ ν리μΌμ΄μ μ λΉλν λ
.env
νμΌ λ±μ ν΅ν΄ νκ²½ λ³μλ₯Ό μ£Όμ ν©λλ€. μ΄ λ°©λ²μ λΉλλ ν΄λΌμ΄μΈνΈ λ²λ€μ κ°μ΄ ν¬ν¨λλ―λ‘, μ¬μ ν κ°λ°μ λꡬλ₯Ό ν΅ν΄ ν€κ° λ ΈμΆλ μ μλ€λ μ μ μΈμ§ν΄μΌ ν©λλ€. λ°λΌμ ν΄λΌμ΄μΈνΈμμ μ§μ μ¬μ©λ μλ°μ μλ곡κ°(public)
API ν€μ νν΄μ μ¬μ©ν΄μΌ ν©λλ€. (μ: Google Analytics ID, 곡κ°μ© μ§λ API ν€ λ±). μ€μν κ²μ ν΄λΉ μλΉμ€μμ μ 곡νλ **λλ©μΈ μ ν(Domain Restrictions)**μ΄λ **IP μ ν(IP Restrictions)**κ³Ό κ°μ μΆκ° 보μ μ€μ μ λ°λμ μ μ©νμ¬ μ€μ©μ λ°©μ§ν΄μΌ ν©λλ€.
ν΅μ¬μ "곡κ°λμ΄λ 무방ν ν€"μ "μ λ 곡κ°λμ΄μλ μ λλ ν€"λ₯Ό ꡬλΆνκ³ , νμμ κ²½μ° λ°λμ μλ² μΈ‘μμ κ΄λ¦¬νλ κ²μ λλ€.
Before Code (Bad)
// src/config.js (λ―Όκ°ν API ν€λ₯Ό μ§μ ν¬ν¨)
export const GOOGLE_MAPS_API_KEY = "AIzaSy_YOUR_SUPER_SECRET_GOOGLE_MAPS_KEY_XYZ123";
export const STRIPE_SECRET_KEY = "sk_test_YOUR_STRIPE_SECRET_KEY_ABC456"; // μ λ 곡κ°λλ©΄ μ λλ λΉλ° ν€!
// src/App.js
import { GOOGLE_MAPS_API_KEY, STRIPE_SECRET_KEY } from './config';
function App() {
// ν΄λΌμ΄μΈνΈμμ λ―Όκ°ν ν€λ₯Ό μ§μ μ¬μ©νλ μ½λ (λ§€μ° μν)
// Google Maps API Keyλ₯Ό μ¬μ©νμ¬ μ§λ λ‘λ
// Stripe κ²°μ μ°λ (μλ² μΈ‘μμ μ²λ¦¬ν΄μΌ ν secret keyλ₯Ό ν΄λΌμ΄μΈνΈμμ μ¬μ©)
console.log("Google Maps API Key:", GOOGLE_MAPS_API_KEY);
console.log("Stripe Secret Key:", STRIPE_SECRET_KEY); // μ΄ ν€λ μ λ ν΄λΌμ΄μΈνΈμ μμΌλ©΄ μ λ©λλ€!
return (
<div>
<p>Your map or payment integration here</p>
</div>
);
}
After Code (Good)
// λ°©λ² 1: νκ²½ λ³μλ₯Ό ν΅ν λΉλ μ μ£Όμ
(κ³΅κ° ν€μ νν¨, Vite.js μμ)
// 1. .env νμΌ (νλ‘μ νΈ λ£¨νΈ λλ ν 리)
// VITE_APP_GOOGLE_MAPS_API_KEY="AIzaSy_YOUR_GOOGLE_MAPS_PUBLIC_KEY_XYZ123"
// (μ°Έκ³ : VITE_ μ λμ¬λ Viteκ° ν΄λΌμ΄μΈνΈ λ²λ€μ λ
ΈμΆν νκ²½ λ³μλ₯Ό μλ³νλ λ°©λ²μ
λλ€)
// 2. src/App.js
function App() {
// 곡κ°μ© API ν€ (μ: μ§λ API, ν΄λΌμ΄μΈνΈ μ μ© λΆμ ν΄ ν€ λ±)
// ν΄λΉ μλΉμ€μμ μ 곡νλ λλ©μΈ/IP μ ν λ± λ³΄μ μ‘°μΉ νμ!
const googleMapsApiKey = import.meta.env.VITE_APP_GOOGLE_MAPS_API_KEY;
console.log("Google Maps API Key (Public):");
return (
<div>
<p>Using environment variables for public keys.</p>
</div>
);
}
// λ°©λ² 2: λ°±μλ νλ‘μ μλ²λ₯Ό ν΅ν μμ ν κ΄λ¦¬ (κΆμ₯, λ―Όκ°ν λΉλ° ν€μ νμ)
// 1. νλ‘ νΈμλ μ½λ: src/api.js
async function processPayment(paymentDetails) {
// ν΄λΌμ΄μΈνΈλ λ―Όκ°ν Stripe Secret Keyλ₯Ό μ§μ μ¬μ©νμ§ μκ³ ,
// λ°±μλ νλ‘μ μλ²μ μλν¬μΈνΈλ‘ κ²°μ μμ²μ 보λ
λλ€.
const response = await fetch('/api/process-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(paymentDetails),
});
if (!response.ok) {
throw new Error('Payment failed');
}
return response.json();
}
// 2. λ°±μλ (Node.js + Express μμ)
// server.js
// require('dotenv').config(); // .env νμΌμμ νκ²½ λ³μ λ‘λ
// const express = require('express');
// const app = express();
// const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); // μλ²μμ νκ²½ λ³μλ‘ μμ νκ² κ΄λ¦¬
// app.use(express.json());
// app.post('/api/process-payment', async (req, res) => {
// const { amount, tokenId } = req.body;
// try {
// const charge = await stripe.charges.create({
// amount,
// currency: 'usd',
// source: tokenId,
// description: 'Example Charge',
// });
// res.json({ success: true, charge });
// } catch (error) {
// console.error('Stripe error:', error);
// res.status(500).json({ message: 'Payment processing failed', error: error.message });
// }
// });
// app.listen(3000, () => console.log('Proxy server listening on port 3000'));