Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Webアプリのセッション管理とデータ保存を学ぶ#2(社内勉強会)

2. Webサービスにおけるデータ保存(クライアントサイド編)

クライアント(ブラウザ)側でのデータ保存について、主流であるCookieをもう少し詳しく見てみましょう。

Cookie

CookieはHTTP仕様で定められているサーバーとクライアント間でHTTPリクエストを跨いだデータをやり取りできる方法の一つです。機能自体はサーバーがHTTPレスポンスの中で短い文字列データをクライアントブラウザ側に保存させ、クライアントブラウザが同じサーバーに通信する時に都度Cookieに保存された内容をHTTPリクエストに送信するといったシンプルな仕様です。
Cookieはクライアントに複数のHTTPリクエストを跨がって同じ文字列を送信させることができるので、ここにセッションIDを入れることでセッション管理を実現できるわけです。

具体的には、サーバーが返すHTTPレスポンスにSet-Cookieヘッダを含めておくと、サーバーが指定した情報がブラウザのCookieに保存されます。Cookie自体には文字列かできるのであれば何でも格納できるため、セッションIDはもちろん商品の入っているカートの状態なども保存できます。

ブラウザは以後同じサーバーにHTTPリクエストを送信するたびに、保存済みのCookieをサーバーに送信します。セッションIDをCookieに含めておけば、サーバーはそれを取り出すことで、HTTPリクエストがどのユーザーの送ったものなのかをセッションIDで判定できるようになります。

morimorihoge注)

CookieはRFC 6265 — HTTP State Management Mechanism (日本語訳)で仕様化されています(リンクは非公式日本語版)。
読んでみると分かりますが、有効期限やドメイン制限などのセキュリティ関連の機能を除くとかなりシンプルな仕様になっています。意識が高まったときに眺めてみるには手頃だと思います :)

Cookieの欠点

Cookieによるクライアント側でのデータ保存は広く定着している手法ですが、いくつかの問題があります。

  • Cookieに保存できるデータのサイズに制限がある (具体的なサイズはブラウザ依存)
  • Cookieはブラウザ側で書き換えられる(JavaScriptからも書き換え可能)
morimorihoge注)

これらの問題からCookieのデータはいつ壊れても大丈夫(システム上やり直しができる)、かつ改竄されても大丈夫なように設計しないといけません。

例えば、RailsにおけるデフォルトのCookieStoreのように、Cookieに暗号化済みのセッションデータを保存することでサーバー側にセッション変数を持たなくても良いようにする方法がありますが、データサイズが大きくなってくるとクライアントブラウザによっては受け入れられるCookie長を超えてしまい、複合不可能な文字列になってしまったりするケースがあり得ます。
サーバー側の開発時にもセッションストレージに何を使っているのかを意識しないと、こうした罠もあるということで。

他にも、セッションIDに推測可能なID(連番やユーザー名など)を使ってしまうとCookieを書き換えることで他人になりすますことが可能になってしまいますし、商品価格のような情報を一時的に入れるのは構いませんが、その値を注文処理でも信用してしまうとユーザー側で勝手に商品価格を書き換えて注文できてしまったりといったバグにも繋がります。

補足: HTML5のWeb Storage

Cookie以外のデータ永続化の方法として、HTML5では以下の2つのWeb Storageが仕様に追加されました。WebStorageはCookieとは違い、より大容量なデータを扱えるようになっているため保存可能なデータ量がCookieよりも大きくなっていますが、保存可能な最大サイズはブラウザの実装に依存しています。

  • SessionStorage: 現在開いているウィンドウやタブの中でのみ使える。閉じた時点でデータは破棄される。
  • LocalStorage: 永続的に保存可能。ブラウザを起動しなおしてもデータを引き継ぐことができる。

Web StorageはCookieとは違いクライアントがブラウザに対してJavaScriptを通して保存させるという手順を取るため、Cookieほどお手軽ではなく、サーバーサイドから書き換えたい場合にはクライアント側のJavaScript実装も必要です。

morimorihoge注)

Web Storageはある程度大きなデータを保持できることからSPA(Single Page Application)でのキャッシュといった利用が主かと思いますが、ユーザー側に見られても良いようなマスタデータのようなものを保管しておくことで、JavaScriptだけで実現できることの範囲を広げるといった利用も可能です。

本来この辺りはWeb SQL Databaseが使えれば良いのですが、主要ブラウザではChrome/Safariくらいしか対応しておらず、IE/Edge/Firefoxで利用できないので、まだまだ大手を振って使える感じはないですね。
※社内システムなどでブラウザを指定できる場合は別ですが

参考: モダンブラウザのストレージ容量と調査方法まとめ - HTML5 Rocks

なお、TechRachoのCookieをChromeブラウザで見ると次のような感じになります(デベロッパーツールの[Application]タブ)。

morimorihogeコメント)

Webの世界は「今動いているものとの後方互換性が大事」という文化が強かったため、今から見ると「なんでこんな制限があるんだろう?」と思う機能が多々あります。Cookieもそんな中の一つです。
それこそ15〜20年前くらいのガラケー全盛期ではCookieが利用できないブラウザというのもあったくらいなのですが、そんな中でも今ある機能を使ってなんとかするという方法が進化してきました。

昨今はPC/スマホ向けについてはバージョン更新の流れが速まり新しい機能も使えるのが当たり前になってきましたが、組み込み向けなどは使われる期間も長いため、レガシな機能についても仕様や制限を把握しておくこと自体は役に立つことがあると思います。
※そして得てして新しい機能のニーズはレガシな機能の延長線上にあるので、なぜその機能が必要とされてきたのかという文脈を知ることにもなります。

関連記事

Webアプリの基礎とさまざまな実行環境を理解する#1(社内勉強会)

Linuxのサービス起動周りとDockerとの関連を理解する#1(社内勉強会)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。