skip to content
barorin&?

Chrome ExtensionからSupabaseにアクセスするときのCORS設定方法(Astroで試しました)

/ 2 min read

はじめに

Chrome ExtensionからSupabaseにアクセスするときのCORS設定方法をご紹介します。
なお、フロントエンドはAstroを使用しています。

方法

Chrome Extension

manifest.jsonhost_permissionsを記載し、fetchする際にmode: "cors"を使用します。

manifest.json

{
    "manifest_version": 3,
    "host_permissions": [
      "https://your-host.com/"
    ],
}

backgrounjd.js

async function add({ postData }) {
  const apiEndpoint = "https://your-host.com/api/chrome-extension";

  try {
    const res = await fetch(apiEndpoint, {
      method: "POST",
      mode: "cors", // COSモードでfetchする
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ postData }),
    });
    if (!res.ok) throw new Error("Server Error");
    return "OK";
  } catch (error) {
    return "NG";
  }
}

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.action === "add") {
    add(request.data)
      .then(sendResponse)
      .catch((error) => sendResponse({ error: error.message }));
    return true; // この関数の応答が非同期であることを示す
  }
});

Supabase

/_shared/cors.ts

どこでもいいので、_sharedというフォルダを作成し、その中にcors.tsを作成します。
cors.tsの中身は下記の通りです。chrome-extension://~は、 Chrome > 拡張機能 > 拡張機能の管理で、各拡張機能のIDで確認することができます。

export const corsHeaders = {
  "Access-Control-Allow-Origin":
    "chrome-extension://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "Access-Control-Allow-Headers":
    "authorization, x-client-info, apikey, content-type",
  "Access-Control-Allow-Methods": "POST",
};

/api/chrome-extension.ts

Chrome Extensionからアクセスされるエンドポイントです。
ここで、上記で作成したcorsHeadersを使用します。

import type { APIRoute } from "astro";
import { corsHeaders } from "../_shared/cors";
import { supabase } from "../lib/supabase";

export const POST: APIRoute = async ({ request }) => {
  if (request.method === "OPTIONS") {
    return new Response("ok", { headers: corsHeaders });
  }

  const { data, error } = await supabase
    .from("examples")
    .insert({ title, url })
    .select("id");

  if (error) {
    return new Response(JSON.stringify({ error: error.message }), {
      headers: { ...corsHeaders, "Content-Type": "application/json" },
      status: 500,
    });
  }

  return new Response(JSON.stringify(data), {
    headers: { ...corsHeaders, "Content-Type": "application/json" },
    status: 200,
  });
};

参考

CORS (Cross-Origin Resource Sharing) support for Invoking from the browser