クッキーを使った認証の流れについて

Railsにおける認証は、deviseというライブラリで簡単に実装できるため、曖昧な理解をしてきた。これを機に整理する。

多くのWebアプリケーションには何らかの認証システムがあります。ユーザーがユーザー名とパスワードを入力すると、Webアプリケーションはそれらをチェックして、対応するユーザーIDをセッションハッシュに保存します。以後、そのセッションは有効になります。リクエストが行われるたびに、Webアプリケーションはセッションで示されたユーザーidを持つユーザーを読み込みます。このときに再度認証を行なう必要はありません。セッションは、cookie内のセッションidによって識別できます。

Rails セキュリティガイド - Railsガイド より

RailsのデフォルトのセッションストレージはCookieStoreというものらしい。この場合、次のような挙動を示すらしい。

Webアプリケーション(認証時)

  • ユーザー名とパスワードをチェック
  • 暗号化したユーザーIDをCookieにSetしてレスポンスとして返す。

Railsのコードで言うとこんな感じ。最近のRailsでは、sessions[:user_id] = @user.id と書くだけでユーザーIDが暗号化されCookieに保存される。

Simple Authentication Guide with Ruby on Rails | by Reinald Reynoso | Level Up Coding より

def create
   @user = User.find_by(username: params[:username])
   if @user && @user.authenticate(params[:password])
      sessions[:user_id] = @user.id
      redirect_to '/welcome'
   else
      redirect_to '/login'
   end
end

CookieにSetしてレスポンスとして返す。と説明したが、具体的には、HTTPヘッダーの中に次のような値を埋め込んでブラウザに返しているだけである。

set-cookie: _myapp_session=ae15f864aecb1e9336a5e281.................................................; path=/

ブラウザ(認証が必要なページへのアクセス時)

ドメインとパスを元に、Cookieがある場合には、CookieをHTTPヘッダーに埋め込んでアクセスしている。

cookie: _myapp_session=ae15f864aecb1e9336a5e281.................................................

Webアプリケーション(認証が必要なページへのアクセス時)

ブラウザから送られてきたCookieを元に、Webアプリケーションは、ユーザーIDを復号化してユーザー情報を取得する。

User.find_by(id: session[:user_id])