プログラミング的なSomething

プログラミング的なSomething

ITエンジニア(?)目線で生活・自転車・トレーニング話を綴ります

Railsでのサインイン・サインアウトの実装

サインインを永続化する

サインインを永続化して、サインアウトしたときにセッションを削除するシステムを考えます。 cookieと認証のためのモジュールであるSessionsHelperを用います。

SessionsHelperモジュールをアプリケーションコントローラにインクルードする

アプリケーションコントローラとはapp/controller/application_controller.rbです。 すべてのヘルパーはビューで使用できますが、コントローラで使用するため、アプリケーションコントローラにincludeします。

include SessionsHelper

伝統的なセッション保持方法

HTTPはステートレスなプロトコルです。そのため、ページ遷移を追跡してセッションを保持します。以下のように固有のIDをcookieに保存します。

session[:remember_token] = user.id

記憶トークン(remember_token)としてユーザーIDといった一意にできる値を利用します。

ページごとの追跡が必要なので、ページが切り替わるたびに以下のようなメソッドでセッション情報を取得します。

User.find(session[:remember_token])

remember_tokenをテーブルに追加する

以下の例では、usersというテーブルにremember_tokenを追加する処理を書いています。 編集が済んだらdb:migrateでテーブルを作りましょう。

rails generate migration add_remember_token_to_users
class AddRememberTokenToUsers < ActiveRecord::Migration
  def change
    add_column :users, :remember_token, :string
    add_index  :users, :remember_token
  end
end

記憶トークンのハッシュ化に関する検討

ユーザーの情報を一意にするIDを平文のまま扱うのは怖いです。たとえ暗号化できていても、不用意にID情報を扱うべきではありません。 そこで、Base64の文字列を用いてremember_tokenを生成します。 記憶トークンはSecureRandamモジュールにあるurlsafe_base64メソッドを使用して生成します。

記憶トークンの生成方法

記憶トークンはユーザー情報の保存前にコールバックを使用して生成することにします。コールバックはbefore_saveを用います。ユーザーが自分の情報を更新する度に記憶トークンが再生成されるため、セッションハイジャックの危険性を軽減してくれます。

Userというモデルを例にすると以下のような書き方になります。

class User < ActiveRecord::Base
  .
  .
  . 
  before_save :create_remember_token
  .
  .
  .
  private

    def create_remember_token
      self.remember_token = SecureRandom.urlsafe_base64
    end
end

before_saveメソッドは、シンボルのメソッドを探索して実行します。 この例では、ユーザー情報の登録前に、create_remember_tokenメソッドが実行され、remember_tokenにSecureRandom.urlsafe_base64で生成された記憶トークンが代入されます。同一モデル内でだけ記憶トークンの生成を行っていればいいので、create_remember_tokenメソッドはprivateになっています。

参考

8章 Ruby on Rails Tutorial