テクノロジー
2017年1月8日login_02

それでは今までの内容を踏まえて、RailsのGemを用いて実際にログイン機能を実装します。
実装方法を確認してみましょう。
認証の仕組みを理解する
それでは今までの内容を踏まえて、実際にログイン機能を実装します。
実装方法を確認してみましょう。
まずはログインのフローを確認していきます。
これを図解すると以下のようになります。これで認証が終わったらクッキーとセッションを使ってログインしているユーザーの情報を保持する動きがなされるのです。
一方で、ログアウトのフローはこのような感じです。
ログイン機能を実装する
いよいよログイン機能を実装していきます。
【手順】ルーティングを定義する
[config/routes.rb]
resources :sessions, only: [:new, :create, :destroy]
【手順】セッションコントローラを作成する
bin/rails g controller sessions
【手順】createアクションを実装する
[app/controllers/sessions_controllers.rb]
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in(user)
current_user
redirect_to root_path, notice: 'ログインしました'
else
flash.now[:alert] = 'メールアドレスまたはパスワードが間違っています'
render 'new'
end
end
createアクションでは以下4つの役割があります。
- emailをキーにしてユーザーをDBから取り出す
- authenticateメソッドでパスワードが一致しているかを確認する
- SessionStoreにuser_idというキーの名前で該当するユーザーのidを格納する
- current_userに該当のユーザを格納する
1と2に関してはアクション内にベタ書きしますが、3は
log_in(user)
4は
current_user
というメソッドをセッションヘルパーに定義します。
【手順】log_inというメソッドをヘルパーに定義する
[app/helpers/sessions_helper.rb]
def log_in(user)
session[:user_id] = user.id
end
【手順】current_userというメソッドをヘルパーに定義する
[app/helpers/sessions_helper.rb]
def current_user
if session[:user_id].present?
@current_user ||= User.find_by(id: session[:user_id])
end
end
【手順】destroyアクションを実装する
[app/controllers/sessions_controllers.rb]
def destroy
log_out if logged_in?
redirect_to root_path, notice: 'ログアウトしました'
end
destroyアクションでは以下2つの役割があります。
- SessionStoreに格納されているuser_idの中身をnilにする
- current_userの中身をnilにする
1と2に関しては
log_out(user)
というメソッドをセッションヘルパーに定義します。
【手順】log_outというメソッドをヘルパーに定義する
[app/helpers/sessions_helper.rb]
def log_out
session.[:user_id] = nil
@current_user = nil
end
さらにログインしているかどうかをチェックするメソッドを定義しておきましょう。
これはログインしているユーザーがnil、つまりcurrent_userがnilでなければtrueが返り、ログインしているとみなされます。
【手順】ログインしているかどうかをチェックできるメソッドを実装する
[app/helpers/sessions_helper.rb]
def logged_in?
!current_user.nil?
end
【手順】newアクションを実装する
先ほどlogged_in?というメソッドを実装したのでそれを元にnewアクションを実装しましょう。
すでにログインしていた場合にトップ画面にリダイレクトさせるコードを実装します。
[app/controllers/sessions_controllers.rb]
def new
if logged_in?
redirect_to root_path, notice: 'すでにログインしています。'
end
end
【手順】usersコントローラのnewアクションを修正する
前回の実装のままでは、ログインしているユーザーでもサインアップが可能になってしまうので、ログインしているユーザーの時はトップ画面へリダイレクトさせます。
def new
unless logged_in?
@user = User.new
else
redirect_to root_path, notice: 'すでにログインしています。'
end
end
【手順】ログイン画面を実装する
[app/views/sessions/new.html.erb]
<h1>ログイン</h1>
<%= notice %><%= alert %>
<%= form_for(:session, url: sessions_path) do |f| %>
<div class="field">
<%= f.label :email %>
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="aciton">
<%= f.submit "ログイン" %>
</div>
<% end %>
<p><%= link_to "ユーザー登録へ", new_user_path %></p>
【手順】トップ画面を実装する
ログインしている時とログインしていない時で表示するリンクを分岐させましょう。これもlogged_in?というメソッドを利用して実装します。
[app/views/top/index.html.erb]
<h1>トップ画面</h1>
<%= notice %>
<% if logged_in? %>
<li><%= link_to "プロフィール", current_user %></li>
<li><%= link_to "ログアウト", session_path(current_user), method: "delete" %></li>
</ul>
</li>
<% else %>
<li><%= link_to "ログイン画面へ", new_session_path %></li>
<li><%= link_to "ユーザ登録", new_user_path %></li>
<% end %>
【手順】セッションの持続時間を設定する
最後にセッション持続時間を設定しましょう。ここを設定してあげないと、ブラウザを閉じた時にセッションが破棄されてしまいます。
[config/session_store.rb]
Rails.application.config.session_store :cookie_store, key: '(アプリ名)_session', expire_after: 15.minutes
【手順】サーバーを立ち上げる
bin/rails s
以上でログイン機能の実装は全て完了しました。
いかがでしたでしょうか?普段Deviseを使っていてログインの仕組みを理解していなかったら、この機会にぜひ理解していきましょう!