ID連携の説明によく出てくる「セッションとの紐づけ」とは
ritou です。
ElixirのTwitter OAuthライブラリ "ExTwitter" の使い方 のようなID連携の説明において 「●●をセッションに紐づけて保存しておきます」 みたいな書き方をよくしますが、これがよくわからんので教えてくれとの質問がありましたのでここにまとめておきます。
特別なことは書いていません。
Webアプリケーションの基本的なセッション管理機能
横文字多めで一言にまとめると、クライアント/サーバー間でステートレスなHTTPを利用するWebアプリケーションにおいて、セッション管理機能により複数のリクエストをまたがり情報を保持できるので、それによりステートフルな仕組みを実現できるみたいな話です。
一般的に、サーバーはセッションIDを(HTTP Cookieとして)クライアントに渡し、それにひもづくデータを(DBなどの)データストアに保持 (ただし、クライアントへの渡し方、クライアントでの保持の仕方、ひもづくデータの持ち方はいろいろ。) といった実装が Web Application Frameworkで行われています。
また、ネイティブアプリやSPA(Single Page Application)の場合、HTTP Cookie以外の仕組みを利用することもあり、これまで散々JWTがどうのこうの言われてきていますが、基本的に クライアントが保持しているトークンやCookieの文字列をHTTP Headerなどで送り続け、サーバー側が検証しその値を利用する ことでセッション管理機能を実現できます。
認証処理が終わったらユーザーIDなどをセッションに紐づけて保存することで、次回以降のアクセスで "ログイン" 状態であることを表現できます。また、予めセッションに紐づけておいた情報を後から利用することも可能です。
ID連携における「セッションとの紐づけ」とは
OAuthのフローとして
- ユーザーは "あるサービス" を利用しており、設定からTwitter連携を有効にする
- あるサービスがTwitterにユーザーの代わりとしての投稿権限を要求し、ユーザーは "Twitter" 上でそれを許可する
- ユーザーは "あるサービス" に戻ると、Twitter連携が有効になっている
みたいなのを "OAuth Dance" と呼びます。
この中で、1と3の処理が同じセッションで行われないと、別の人と自分のTwitterアカウントを紐づいたり、自分と別の人のTwitterアカウントが紐づいたりするリスクがあります。
そこで、"あるサービス" 側は1と3のところでセッション管理機能を利用して、OAuthの処理で扱われるパラメータを用いて"同一セッションであること"を検証したり、1である値をセッションに紐づけて保持し、3で利用するような処理ができます。
既存のセッション管理機能がない場合、あっても利用しない場合
既存のセッション管理機能を使わなくても、この用途だけにセッションID的な識別子を持ったCookieやトークンを発行し、データを紐づけることもできるでしょう。ただし、セッション管理における脅威や対策などをよく理解した上で作らないと、後々問題が起こる可能性もあります。
用途ごとに仕組みを分けることで無効化も簡単でしょうし、何か問題があった際の被害を分散させることも期待できそうですが、その分管理コストもかさむことは気に留めておく方が良さそうです。
セッションIDのみがいいか、暗号化したデータが良いか
要件によって、セッション管理の設計も変わってくるでしょう。
- HTTP Cookie仕組みにおける有効期限をセットしても、ブラウザの利用者が書き換えたりできるので有効期限も保持する
- DBなどを使わずJWT形式などで内包する場合、エンコード&署名つきのJWSの場合は含まれる情報を把握される可能性があるのでJWEにする
この話を詰めていくとOAuthのアクセストークンの実装パターンのようなお話にもなりますが、まずは既存のセッション管理の仕組みが問題なければそっちを使う方が良いとは思います。
まとめ
Zennでは基本的なお話をクセ弱めで投稿をしていこうと思います。
クセの強い話は引き続きブログで。
ではまた!
Discussion