Webアプリのセッション管理とデータ保存を学ぶ#1(社内勉強会)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。Webアプリの開発初心者、または書いたことはあるけどサーバーやインフラについてはよく分かっていない人向けです。Webアプリを「データや状態の保存」という観点からクライアント側とサーバー側について説明します。Webアプリのセッション管理の基礎HTTPプロトコルはステートレスなので、そのままではデータや状態を次のHTTPセッションに引き継げません。このままでは掲示板や商品購入や支払い機能を作れないので、何らかの形で状態を維持するしくみが必要です。moirmorihoge注)ステートレスとステートフルの違いについては以前の記事を先に読んでおくと良いでしょう。状態)管理機能には、以下の要件が求められます。HTTPリクエストを受け取ったときに、同じユーザーからのアクセスを「これは以前のこのリクエストと同じ一連のアクセスである」と判別する必要があります。これができないとログイン状態を保持するといったことができません。ユーザーごとにステートを分けて管理することが求められます。同じ「マイページ」のURLにアクセスしていても、Aさんの「マイページ」とBさんの「マイページ」はログインしているユーザーによって異なるものが表示されるのが一般的です。※もちろんAさんでログインしていたのにリロードするたびにBさんの情報が見えたりするのもダメですね最後に、これは必須ではありませんが、ステートを保持したうえで、ステートに保存された情報はなるべく少なくしたいというのがあります。ログイン済みのHTTPリクエストの度にユーザーIDとパスワードを毎回送ったり、ショッピングカートに入れた注文情報を都度送るというのはできなくはないですが、サーバー側のデータが変わらないのであれば毎回クライアントーサーバ間で受け渡しをするのはオーバーヘッドが大きいですしね。HTTPプロトコルでは状態を「ステート」という用語で表していますが、Webページの場合はステートを「セッション」と呼び、ステート管理を「セッション管理」と呼びますので、以後この呼び方で統一します。そこで、Webサービスでは何らかの形で「セッションID」というものをユーザーごとに持たせ、これを頼りにセッションを管理するという戦略を取ります。静的Webサービスのように、常にWebサーバーがアクセス元に関係なく同じレスポンスを返すような状態のないWebサービスであればセッションを管理しなくても成立しますが、ほとんどの場合はセッション管理を行います。morimorihoge注)カタログサイト(注文処理を含まない)などではセッション不要な例もありますが、「お気に入り」機能や「閲覧履歴」みたいなものを出そうとすると結局セッション管理が必要になってくることもよくあります。※もっとも、この程度であればCookieにデータを格納するという手もありますWebサービスでは、何らかの形でセッションIDというものをユーザーごとに持たせるという考え方でセッション管理を行います。ユーザーからのHTTPリクエストに含まれるセッションIDが同じであれば、同じユーザーからのリクエストであるとみなします。セッションIDの具体的な管理方法の種類について、次で説明します。セッション管理の手法Webサービスにおけるセッション管理の手法はいくつかあります。Cookieを使う方法です(上の図でも既にCookieを使う例で説明しています)。GET/POSTリクエストパラメータGET/POSTリクエストパラメータ(クエリパラメータとも呼ばれます)はセッションIDをリクエストURIのパラメータの一部に含める方式です。URIで?で始まる長めのパラメータが付いているのを見たことのある人も多いと思います。この方式はどのブラウザでも確実に使えます。その昔のガラケーはCookieが使えない時代があったため、ガラケー対策として使われていました。その代り、すべてのGETリクエストのパラメータに明示的にセッションIDを付けないとセッションを維持できません。したがって、GETリクエストのURIにセッションIDが常に丸見えになってしまいます。morimorihoge注)この手法はユーザー登録時のメールアドレス認証などのごく限られた場合を除き、現在推奨されません。危険なのは検索エンジンのクローラがセッションID付きのURLをキャッシュしてしまった場合で、正しくセッションIDのリセット処理を行っていない場合には最悪一部のユーザーの情報漏洩に繋がる可能性があります。サイトを見ているユーザーが友人や同僚に今見ているページのURLを共有しただけでもセッションIDが漏洩してしまう可能性があります。レガシーシステムとの統合等でどうしても使わざるを得ない場合には、IPアドレス制限やBasic認証などの他の認証方式も併用するのが安全(まだマシという程度)でしょう。CookieRailsも含めて現在最も一般的に使われているのが、Cookieによるセッション管理です。CookieはサーバーはHTTPリクエストの中(Cookieヘッダ)から、ブラウザであればJavaScriptから読み書きできます。Cookieを使う場合、GET/POSTパラメータ方式とは異なり一般的なHTTPサーバーのログには記録されないことや、一度生成されたセッションIDの破棄タイミングなどをHTTPのCookie機能(expires値など)を使って管理することができる利点があります。morimorihoge注)Cookie中のデータはHTTPリクエストに含まれているので、中間にあるProxyサーバーやネットワーク上に悪意のあるホストがいる場合には覗き見ることは可能です。Cookieに機密情報を含めてやり取りしたい場合には、SSL/TLSを使ったHTTPS通信で行うようにしましょう。言うまでもない話ですがCookieの内容はクライアント側が常に任意に読み書き可能なので、ログインセッションなどの重要な情報を扱う場合には、暗号化したり署名を付けるなどの方法で改竄を防止するといった対策を行うのが一般的です。上の2つの代表的なセッション管理方法以外にも次の方法があります。クライアント証明書型は、クライアント証明書に含まれるユーザ情報をセッションID(ログイン情報)として使います。ユーザー発行型は、セッションIDをユーザー側(ブラウザのJavaScriptなど)で作成するもので、送受信そのものは上述のCookieやリクエストパラメータを使います。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。