0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS CloudFront】302がキャッシュされて画像が見れない問題とその対処法(Lambda@Edge + Nginx)

Posted at

【AWS CloudFront】302がキャッシュされてがぞう見れない問題とその対処法(Lambda@Edge + Nginx)

CloudFront を使っていて、302リダイレクトがキャッシュされてしまい、ユーザーが正しくページを見れないという問題に直面したことはありませんか?

この記事では、CloudFrontが302レスポンスをキャッシュしてしまう問題の対処法と、それに伴うExpress.jsの副作用Nginxを使った回避策について紹介します。


🧨 発生した問題:CloudFrontが302をキャッシュしてしまう

CloudFront はデフォルトで 200以外のレスポンス(302など)もキャッシュする ことがあります。
これにより、一時的なリダイレクトがずっとキャッシュされてしまい、本来表示されるべきページが見られなくなるという事象が発生しました。


💡 解決策:302レスポンスにはキャッシュさせない

✅ 方法① Lambda@Edgeで Cache-Control: no-store を付与

CloudFrontのオリジンレスポンスに対してLambda@Edgeを使い、ステータスコードが200以外のときだけキャッシュさせないようにします。

exports.handler = async (event) => {
  const response = event.Records[0].cf.response;
  const statusCode = parseInt(response.status);

  if (statusCode !== 200) {
    response.headers['cache-control'] = [{
      key: 'Cache-Control',
      value: 'no-store'
    }];
  }

  return response;
};

ポイント:302などの一時的リダイレクトをCloudFrontでキャッシュさせないようにする。


✅ 方法② CloudFrontのカスタムエラーページのTTLを制御

CloudFrontのエラーページ設定でも、キャッシュ期間を短く制御できます。

設定項目
最小 TTL 0
最大 TTL 600
デフォルト TTL 300

これにより、万が一キャッシュされても 短時間で再評価される ようになります。


⚠️ 問題再燃:Express.jsが自動で Cache-Control を付与してしまう

ここで新たな問題が発生。

Express.js はデフォルトで Cache-Control: public, max-age=xxx を自動的に付与します。
この挙動により、302以外のレスポンスも含めて一律にキャッシュ設定され、静的ファイルも含めてキャッシュされなくなる という副作用が発生しました。


✅ 回避策:Nginxで強制的に Cache-Control ヘッダーを上書き

Express.js 側で細かく制御するのが難しかったため、Nginxをリバースプロキシとして挟み、特定のレスポンスだけキャッシュヘッダーを外す構成にしました。

location / {
    proxy_pass http://localhost:3000;
    
    # 302 の場合は Cache-Control を外す
    proxy_intercept_errors on;
    add_header Cache-Control 'no-store' always;
}

※ 状況に応じて add_headerif 条件を付けたり、ルールを細かく書き分けることも可能です。


🧪 最終的な構成まとめ

CloudFront
  └── Lambda@Edge(200以外のレスポンスに no-store)
        └── Nginx(Cache-Controlの強制制御)
              └── Express.js(静的ファイル配信)
  • ✅ CloudFrontのキャッシュは必要最小限に
  • ✅ Lambda@Edgeでステータスベースに振り分け
  • ✅ Express.jsの意図しないキャッシュはNginxで上書き

🎯 まとめ

課題 解決策
CloudFrontが302をキャッシュしてしまう Lambda@Edgeで Cache-Control: no-store を付与
エラーページが長くキャッシュされる TTLを最小0、最大600、デフォ300に設定
Expressが自動でキャッシュを付与する Nginxで強制的に上書きする

👀 おわりに

CloudFrontでのキャッシュ制御は非常に強力ですが、一歩間違えるとユーザー体験を壊してしまう危険もあります。
本記事のような「200以外のレスポンスに対する適切なキャッシュ制御」は、特に認証リダイレクト一時的なページ移動が発生するサービスでは重要です。

同じようなことでハマってる人の参考になれば幸いです!


📚 参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?