링크 드라퍼 익스텐션은 단순한 북마크 저장기가 아닙니다.
로그인한 사용자 정보를 기반으로 서버에 요청을 보내고, 그 결과에 따라 링크를 저장하죠.
그래서 필연적으로 외부 API 연동이 필요했고,
여기서부터 진짜 실전 개발이 시작됐습니다.
익스텐션은 일반 웹앱과 달리, 브라우저 탭과 분리된 환경에서 돌아갑니다.
특히 popup이나 background에서 API 요청을 보내면,
자동으로 쿠키가 붙지 않는 경우가 많았습니다.
// background script 내부에서 fetch 호출
fetch("https://link-dropper.com/api/me", {
credentials: "include"
});
// 서버 응답: 401 Unauthorized
chrome.cookies.get() 활용chrome.cookies.get({ url: "https://link-dropper.com", name: "session_token" }, (cookie) => {
if (cookie) {
chrome.storage.local.set({ session_token: cookie.value });
}
});
// 이후 fetch 시 Authorization 헤더에 붙여 사용
chrome.storage.local.get("session_token", async ({ session_token }) => {
await fetch("https://link-dropper.com/api/me", {
headers: {
Authorization: `Bearer ${session_token}`
}
});
});
주의: 이 API는 content script에서는 사용할 수 없고, 반드시 popup or background에서 실행해야 합니다.
“Access to fetch at 'https\://...' from origin 'chrome-extension://...' has been blocked by CORS policy”
익스텐션 환경에서는 기본 fetch 요청도 다르게 동작합니다.
특히 background script는 CORS 제약을 덜 받지만,
popup이나 content script는 엄격한 동일 출처 정책을 따릅니다.
{
"host_permissions": ["https://link-dropper.com/*"],
"permissions": ["cookies"],
...
}
app.use(cors({
origin: ["chrome-extension://<YOUR_EXTENSION_ID>", "http://localhost:3000"],
credentials: true,
}));
Vite + MV3 조합에서는 .env 파일의 내용이 그대로 클라이언트에 노출될 수 있습니다.
예시:
console.log(import.meta.env.VITE_SECRET_API_KEY); // 🚨 노출됨
.env 파일 분리 관리VITE_ prefix를 붙여야 클라이언트 코드에서 사용 가능.env.development / .env.production 으로 자동 분리 가능# .env.development
VITE_API_URL=http://localhost:4000
fetch(`${import.meta.env.VITE_API_URL}/api/links`);
process.env를 통해 민감 정보 직접 주입 가능// vite.config.ts
export default defineConfig({
define: {
__API_URL__: JSON.stringify(process.env.API_URL),
},
});
// 코드 내부에서 안전하게 사용
fetch(`${__API_URL__}/api/secure-endpoint`);
manifest.json은 사용자가 직접 확인 가능한 파일background.ts는 브라우저 탭에 노출되지 않음// background.ts
const API_KEY = import.meta.env.VITE_INTERNAL_API_KEY;
// client → proxy API → external API
fetch('/api/proxy?target=og-data&url=https://example.com');
// server-side
const result = await fetch(`https://api.external.com?url=${url}`, {
headers: { 'Authorization': `Bearer ${API_SECRET}` }
});
이처럼, 환경변수는 기능과 보안 수준에 따라 분리해서 관리하는 것이 중요합니다.
Vite + MV3 조합에서는 .env 파일의 내용이 그대로 클라이언트에 노출될 수 있습니다.
예시:
console.log(import.meta.env.VITE_SECRET_API_KEY); // 🚨 노출됨
// vite.config.ts
export default defineConfig({
define: {
__API_URL__: JSON.stringify(process.env.VITE_API_URL),
},
});
// 실제 코드에서는 전역 상수로 참조
fetch(`${__API_URL__}/api/secure`) // 안전하게 분리 가능
링크 저장 후 사용자를 폴더 관리 페이지로 유도하거나,
팝업이 끝나면 자동으로 닫히도록 UX 개선을 진행했습니다.
// 새 탭 열기
chrome.tabs.create({ url: "https://link-dropper.com/folders" });
// 현재 탭 닫기
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs[0]?.id) {
chrome.tabs.remove(tabs[0].id);
}
});
이번 글에서는 크롬 익스텐션에서 외부 API를 연동하며 마주친 다양한 문제들과 그 해결 방법을 정리해봤습니다.
다음 글에서는 MV3 기반 크롬 익스텐션을 실제로 배포하는 과정과
스토어 등록 시 주의할 점, 권한 검토 통과 팁 등을 정리해보려 합니다.
놓치지 말고 확인해 주세요!
익스텐션에서 외부 API 연동은 단순해 보이지만,보안 + 브라우저 정책 + 쿠키 + CORS + UI 피드백까지 신경 써야 할 요소가 많습니다.
이번 글에서는 우리가 직접 겪은 시행착오와 함께,
실제 사용자를 위한 기능 완성까지 어떻게 해결했는지를 공유해봤습니다.
링크 드라퍼는 단순한 저장 툴이 아닙니다.
정리하고, 수정하고, 다시 꺼내보게 만드는 링크 관리 도구를 지향하고 있습니다.
• 🔗 빠르고 간편한 링크 저장
• 🧠 저장한 링크를 폴더별로 정리
• 🌐 폴더를 친구에게 공유 가능
• ⚡ OG 미리보기 자동 불러오기
직접 써보시고, 익스텐션에서의 기능이 어떠셨는지도 알려주세요!