[Rails]acts_as_authenticatedを使う

ログイン、認証周りの処理を作成するのに使えるかと思い調べてみた。

インストール

インストール等については、以下を参照した。

プラグインインストール後、認証に対応したモデルとコントローラを生成する。

$ ruby script/generate authenticated MODEL CONTROLLER

概要

上記手順を実行すると、以下のファイルが生成される。

  • app/models/user.rb
  • app/controllers/account_controller.rb
  • app/views/account/index.rhtml
  • app/views/account/login.rhtml
  • app/views/account/signup.rhtml
  • lib/authenticated_system.rb

できそうなことは、大体以下のような感じ。

  • サインアップフォームによるユーザ登録
  • ログイン処理
  • ログアウト処理
  • 非ログイン時のアクション実行禁止

カスタマイズ

とりあえず今回はサインアップの機能は入らないのでごっそり削除したのと、自前で用意したホーム画面を表示したいので、Controllerのあたりをゴリゴリ書き換えた。
また、自前のホーム画面を表示するためにhomeアクションを追加している。いろいろ弄った結果、こんな形になった。

class AccountController < ApplicationController
  # Be sure to include AuthenticationSystem in Application Controller instead
  include AuthenticatedSystem
  # If you want "remember me" functionality, add this before_filter to Application Controller
  before_filter :login_from_cookie

  # say something nice, you goof!  something sweet.
  def index
    if logged_in? then
      redirect_to(:action => 'home')
    else
      redirect_to(:action => 'login')
    end
  end

  def login
    redirect_to :action => 'home' if logged_in?
    return unless request.post?

    self.current_user = User.authenticate(params[:login], params[:password])
    if logged_in?
      if params[:remember_me] == "1"
        self.current_user.remember_me
        cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
      end
      flash[:notice] = "Logged in successfully"
      redirect_to :action => 'home'
    end
  end

  def home
    if logged_in? then
      @members = current_user.members
    else
      redirect_to :action => 'login' unless logged_in?
    end
  end

  def logout
    self.current_user.forget_me if logged_in?
    cookies.delete :auth_token
    reset_session
    flash[:notice] = "You have been logged out."
    redirect_to :action => 'login'
  end
end

非ログイン時のアクション実行禁止

Controller内に以下の記述をするだけ。非ログイン時にはaccountコントローラのloginアクションが実行されるみたい。

  include AuthenticatedSystem
  before_filter :login_required

ここら辺の動きの詳細は authenticated_system.rb 内の login_required -> access_denied メソッドを読めばわかる。