Stripe Apps向けのAPIを作るときの、CORS設定についての覚書

Stripe Appsから外部APIを呼び出す際のCORS設定の落とし穴と対処法について。Stripe Dashboardの実行環境の仕様により、originがnullになるため、緩めのCORS設定が必要。代わりに署名検証を行い、セキュリティを確保する必要がある。

広告ここから
広告ここまで

目次

    Stripe Appsに公開するアプリを作っていると、サーバー側の処理を実行するためにREST APIを呼び出すことがあります。その際にハマりがちなポイントについてまとめました。

    Stripe Appsから呼びだすAPIのCORSどうするの問題

    Stripe Appsはセキュリティ上の問題からも、CORSをはじめとしたセキュリティ対策がStrict気味に運用されています。なので外部のAPIを呼び出す時は、CORSの設定をしておく必要があります。ただ、HonoのようなAPIサーバーを実装しているときに、originにStripe Dashboardの URLを指定すると、思わぬハマりポイントが発生します。

    app.use('*', cors({
        origin: 'https://dashboard.stripe.com', // Stripe Dashboardからのリクエストのみを許可
        allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
        allowHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
        exposeHeaders: ['Content-Length', 'X-Requested-With'],
    
        maxAge: 86400, // プリフライトリクエストのキャッシュ期間(秒)
        credentials: true, // Cookieを含むリクエストを許可する場合
      }))

    Stripeダッシュボードから呼び出すのだから、このoriginでいけるかなーと思ったのですが、これだとCORSエラーを解消できません。不思議に思ったのでoriginがどうなっているかを覗いてみました。null。

    app.use('*', async (c, next) => {
      // リクエスト元のOriginを取得
      const origin = c.req.header('Origin') || 'Origin not specified';
      
      // リクエスト情報をログに記録
      console.log(`Request from Origin: ${origin}`);
      console.log(`Request URL: ${c.req.url}`);
      console.log(`Request Method: ${c.req.method}`);
      
      // リクエストヘッダーの詳細をログに記録(オプション)
      console.log('Request Headers:', JSON.stringify(c.req.header(), null, 2));
      
      
      // 通常のリクエスト処理
      await next();
      
      // レスポンスヘッダーに動的にOriginを設定
      if (origin !== 'Origin not specified') {
        c.res.headers.set('Access-Control-Allow-Origin', origin);
        c.res.headers.set('Access-Control-Allow-Credentials', 'true');
      }
      
      // レスポンス情報をログに記録
      console.log(`Response Status: ${c.res.status}`);
      console.log(`Response Headers:`, JSON.stringify(Object.fromEntries(c.res.headers.entries()), null, 2));
    });
    

    びっくりしたのが、このコードを実行したところ、なんとoriginがnullでした。Stripe Appsアプリはsandbox環境で実行していると聞いていたのですが、そのあたりの仕様がかんけいしているのかもしれません。

    CORSは緩めに、署名検証で保護するしか・・・ない?

    originがnullになる以上、緩めの設定をするしかないのかなーという認識に至っています。

    app.use('*', cors())

    CORSが緩めになる代わりに、署名検証処理を追加することで保護していこうかなととりあえずは思っています。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark