セッションベース認証まとめ

セッションベース認証について調べたことをまとめます。

セッションベース認証 概要

セッションベース認証は、主にセッションIDを用いて行う認証方式です。 基本的なフローは以下です。 まずユーザが認証画面で認証情報を入力しwebサーバに情報を送ります。webサーバは認証情報をチェックし、正しければセッションIDというランダムな文字列を生成しユーザ情報と紐付けます。それをクライアント(ブラウザ)に返し、以降のやり取りにセッションIDを含めることでログイン状態を維持します。セッションIDのやり取りは主にCookieを使います。

Cookieとは

Cookieとは、Webサーバがクライアント(ブラウザ等)に預けておく小さなファイルのことを指します。 ブラウザ・サーバ間でCookieをやり取りする際はHTTPのリクエストヘッダ(Cookieフィールド)・レスポンスヘッダ(Set-Cookie)に格納することでCookieのやりとりを行います。

具体的な動きを見てみます。

f:id:surfi8000:20220119111506p:plain

① ユーザはログイン画面で認証情報を入力しサーバに送ります。 ② 送られてきた認証情報が正しい場合、サーバはそのデータをレスポンスに含めます。 具体的には以下のようにレスポンスヘッダのSet-Cookieフィールドにデータを入れます。Set-Cookieは、ブラウザにデータをCookieとして保存してくれ、という命令です。

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: id=123
Set-Cookie: passwd=hogehoge

③ レスポンスを受け取ったブラウザはSet-Cookieフィールドからデータを取り出し、ブラウザのCookieに保存します。次回リクエストの時には以下のようにCookieをリクエストヘッダのCookieフィールドに含め送信します。

GET /index.html HTTP/2.0
Host: www.example.org
Cookie: id=123; passwd=hogehoge

具体的にブラウザのCookieにデータを保存するにはJavaScriptDocument.cookieを使い以下のようにします。

document.cookie = "id=123";
document.cookie = "passwd=hogehoge";

参考:

Document.cookie - Web API | MDN

④ リクエストヘッダからCookieに含まれる認証情報をチェックし、正しい情報であればレスポンスする、などします。

Cookieの基本的な動きは以上です。

Cookieの性質

RFC2109によると、Cookieには以下の性質があります。

項目 説明
保存形式 テキスト
cookieの全数量 少なくとも300個
ドメイン毎のcookieの数量 少なくとも20個
1つのcookieの容量 4096byte
有効期限 設定可能(未設定の場合はブラウザ終了時に削除)
異なるブラウザ間の共有 不可
有効範囲 domainオプションを付けない限り、Cookieが有効なオリジンに限る

有効範囲についてですが、設定しない限りCookieは異なるオリジン(scheme://hostname:port の組み合わせ、URL)には送信されないということです。

以上のことから、Cookieには以下のような問題点があります。

  • CookieはHTTPリクエストヘッダ・レスポンスヘッダを利用するので盗聴、漏洩リスクが高い
  • Cookieをブラウザに保存する場合、テキストで保存される上簡単な操作で見られるので漏洩の危険性がある
  • Cookieに格納できる上限は4096バイト(超えた部分は削除)

よって、重要データや容量の大きなデータをやり取りする場合はCookieは適していないことがわかります。

なので、ログイン状態の保持は認証情報を直接やり取りする方法ではなく、セッションIDを用いるセッションベース認証が使われることが多いです。

セッションベース認証とは

上記の特徴により認証情報そのものをCookieでやり取りするのは危険なので、そこで考え出されたのがセッションベース認証です。 セッションベース認証では、セッションIDと呼ばれる文字列を生成しそれをユーザ情報と紐付け、都度リクエスト時にセッションIDをCookieに含めることで認証状態を保持します。

f:id:surfi8000:20220119111529p:plain

このように、セッションIDをCookieでやり取りすることで、リクエストを受けたサーバはセッションIDに紐づくユーザ情報を探し存在していればそのユーザをログイン済みと見なします。

セッション情報はインメモリDBで管理

セッション情報はユーザからのリクエストのたびに参照されるため、高速に処理する必要があります。 ですので、セッション管理はRDBではなくRedisのようなインメモリデータベースで管理することが多いです。

このようなセッションを利用した認証をセッションベース認証と呼びます。