【Rails】 Authlogicでユーザー認証機能

ユーザー登録機能を作成する

・モデルを作成する

$ rails g model User

・マイグレーションファイルを修正する

# db/migrate/20130125121017_create_users.rb

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string    :email,             null: false
      t.string    :crypted_password,  null: false
      t.string    :password_salt,     null: false
      t.string    :persistence_token, null: false
      t.timestamps
    end
  end
end
$ rake db:migrate

・コントローラーを作成する

$ rails g controller Users

・ルーティングを追加する

# config/routes.rb

resources :users, only: :create
get "signup" => "users#new"
# app/controllers/users_controller.rb

class UsersController < ApplicationController
  # GET /signup
  def new
    @user = User.new
  end

  # POST /users
  def create
    @user = User.new(user_params)

    if @user.save
      redirect_to root_url
    else
      render action: :new
    end
  end

  private

    def user_params
      params.require(:user).permit(:email, :password, :password_confirmation)
    end
end


・ビューを作成する

# app/views/users/new.html.erb

<%= form_for @user, url: users_path do |f| %>
  <fieldset>
    <legend>Sign up</legend>
    <p>
      <%= f.label :email %>
      <%= f.text_field :email %>
    </p>
    <p>
      <%= f.label :password %>
      <%= f.password_field :password %>
    </p>
    <p>
      <%= f.label :password_confirmation %>
      <%= f.password_field :password_confirmation %>
    </p>

    <%= f.submit "sign up", class: "btn btn-primary" %>
  </fieldset>
<% end %>

・ユーザー登録画面を表示してみる
http://localhost:3000/signup

※ まだ登録できないので次のステップへ〜。

認証機能を作成する

・Authlogic をインストールする

# Gemfile

gem 'authlogic'
$ bundle install

・認証に必要なメソッドを追加する

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  ...

  helper_method :current_user, :logged_in?
  before_filter :require_login

  private
    def current_user_session
      return @current_user_session if defined?(@current_user_session)
      @current_user_session = UserSession.find
    end

    def current_user
      return @current_user if defined?(@current_user)
      @current_user = current_user_session && current_user_session.user
    end

    def require_login
      unless current_user
        redirect_to login_url
        return false
      end
    end

    def logged_in?
      current_user_session != nil
    end
end

※ current_userメソッドを定義し、アプリケーションのビューのコードの中でも呼び出せるように設定する
※ require_loginメソッドを定義し、アクションへのアクセスを制限を設定する
※ ログインしていない場合はログイン画面へ遷移する

・モデルを作成する

# app/models/user_session.rb

class UserSession < Authlogic::Session::Base
end

・email でログインできるようにする

# app/models/user.rb

class User < ActiveRecord::Base
  # for authlogic
  acts_as_authentic do |c|
    c.login_field = :email
  end
end

・コントローラーを作成する

$ rails g controller UserSessions
# config/routes.rb

resource :user_session, only: :create
get "login" => "user_sessions#new"
delete "logout" => "user_sessions#destroy"
# app/controllers/user_sessions_controller.rb

class UserSessionsController < ApplicationController
  skip_before_filter :require_login, only: [:new, :create]

  # GET /login
  def new
    @user_session = UserSession.new
  end

  # POST /user_session
  def create
    @user_session = UserSession.new(params[:user_session])

    if @user_session.save
      redirect_to root_url
    else
      render action: :new
    end
  end

  # DELETE /logout
  def destroy
    current_user_session.destroy
    redirect_to login_url
  end
end
# app/views/user_sessions/new.html.erb

<%= form_for @user_session, url: user_session_path do |f| %>
  <fieldset>
    <legend>Login</legend>
    <p>
      <%= f.label :email %>
      <%= f.text_field :email %>
    </p>
    <p>
      <%= f.label :password %>
      <%= f.password_field :password %>
    </p>
    <%= f.submit "Login", class: "btn btn-primary" %>
  </fieldset>
<% end %>

・ユーザー登録では require_login を通さないようにする

# app/controllers/users_controller.rb

skip_before_filter :require_login, only: [:new, :create]

・リンクを追加する

# app/views/layouts/application.html.erb

<% if logged_in? %>
  <%= link_to "ログアウト", logout_path, method: :delete %>
<% else %>
  <%= link_to "ログイン", login_path %>
  <%= link_to "新規登録", signup_path %>
<% end %>


・ログインできることを確認する
http://localhost:3000/login

2013.6.22追記 Rails4対応