Cache-Controlのprivateとpublicは共有cacheに保存してよいresponseかで分ける
公開日: 執筆:佐藤
Cache-Control: privateは、login後の会員情報や注文履歴のように、一人へ返すresponseを共有cacheへ保存させないために使います。publicは、共有cacheでも保存できることを示します。二つは表示を速くする設定と安全性の設定を一語で済ませるものではありません。誰に同じ内容を返すpageか、誰の情報が入るpageかを先に分けます。
公開pageにcacheを使うことと、個人情報が入るpageを保存しないことは、同じ判断ではありません。画像や会社案内のように多くの読者へ同じ内容を返すresourceと、loginした利用者の住所や申込み内容を返すresourceでは、返す内容と保存してよい範囲が違います。URLの見た目だけで決めず、responseの本文とheaderを確認します。
shared cacheとbrowserの保存を同じ意味にしない
HTTPのcacheには、利用者のbrowserが持つcacheだけでなく、複数の利用者にresponseを返すshared cacheがあります。hostingやnetworkの構成によっては、serverの手前にcache serverやCDNを置く場合があります。privateは、responseが一人の利用者向けであり、shared cacheが保存してはならないことを示します。利用者自身のbrowserが保存するかどうかまで、一律に禁止するdirectiveではありません。
反対に、publicはshared cacheがresponseを保存できることを示します。公開した記事、画像、CSS fileのように、利用者ごとに内容を変えないresourceでは候補になります。ただし、URLが公開されているからといって、必ずpublicを付けるわけではありません。query parameterやcookieで表示内容が変わるpage、管理者だけが見るpreview、短い時間で内容が変わる在庫表示などは、同じURLでも返る内容を確認します。
説明用の仮例として、通販siteに/products/tea-setと/account/ordersがあるとします。前者は商品説明と写真を表示し、誰が見ても同じ説明を返すなら、publicなresourceとしてcacheを検討できます。後者はloginした利用者ごとの注文履歴を返すため、shared cacheへ保存させないことが必要です。二つのURLを同じheaderにそろえるのではなく、本文が誰のためのdataかを見ます。
privateとno-cacheとno-storeは役割が違う
privateはshared cacheでの保存を制限します。保存したresponseを再利用する前にorigin serverへ確認させたいときは、no-cacheが関係します。どのcacheにも保存させたくない事情があるときは、no-storeを検討します。directiveの名前だけで強い方を選ぶと、必要な表示や更新の確認まで不安定にします。
たとえば、利用者ごとの注文履歴では、shared cacheから別の利用者へ返らないようにすることが先です。内容を更新した直後に古い表示を出したくないなら、保存の可否とは別に、再利用前の確認方法を決めます。カード番号のように保存そのものを避けるべきdataなら、pageへ出す設計、log、画面の表示時間、server側の管理を含めて見直します。no-storeを一つ付ければ、すべてのdata管理が済むわけではありません。
ここで、管理画面のresponseをprivateにして安心するのも早すぎます。共有cacheの制限は重要ですが、他人が利用者の端末を操作できる、画面を印刷する、browserにlogin状態が残るといった問題までは解決しません。login、logout、権限、端末の管理と、HTTP headerの設定を別の対策として扱います。
cookieがあるpageは本文を実際に比べる
cookieを使うpageは、利用者ごとに内容が変わる可能性があります。しかしcookieが付いているだけで、すべてをcacheできないと決めるのではありません。language設定、閲覧済みの表示、管理者向けの操作buttonなど、cookieが何を変えるかを確認します。重要なのは、別の利用者へ返したときに困る本文やheaderが混じるかどうかです。
仮に、公開記事のpageで管理者だけに編集linkを出しているとします。本文は公開情報でも、編集linkや管理用のtokenを含むresponseをshared cacheから返せば困ります。表示用のpageと管理用の操作を同じresponseへ混ぜない、管理時はcacheを使わないといった設計が必要になります。headerだけを変える前に、何を同じresponseへ入れているかを見ます。
WordPressを使うsiteでは、login状態、preview、買い物かご、問い合わせの確認画面、管理画面を公開記事と同じように扱いません。themeやplugin、hostingのcache機能がheaderを付け替える場合もあります。管理画面で設定を保存したことではなく、loginしていない状態とloginした状態で対象URLを開き、response headerと本文の両方を見ることが必要です。
設定前後は利用者を変えて確認する
確認は一つのbrowserだけで終わらせません。まず、対象URLを公開情報、一人向け情報、管理用の操作を含むpageに分けます。次に、それぞれへ返すCache-Control headerを記録します。その後、loginしているwindowとloginしていないwindow、可能なら別の利用者で同じURLを開き、本文、名前、注文内容、操作linkが混ざらないかを確認します。
cacheを消して表示が直っただけでは、設定が正しい証拠になりません。何を保存したcacheがあり、どの時刻にそのresponseを返したかを確認します。CDNやhostingのcacheを使う場合は、設定を変える担当、cacheを消す担当、確認する担当を決めます。更新担当が本文だけを直し、cache設定を知らない状態では、利用者によって違う表示が残ることがあります。
最初の一手は、login後に開くURLを一つ選び、そこに氏名、住所、注文内容、管理用の操作が含まれるかを書き出すことです。次にloginしていない状態と別の利用者で開き、同じresponseを返してよいpageかを確かめます。その結果からprivate、public、再確認、保存を避ける設計を選びます。
関連記事

