Action Cableの習作: Examplesの更新: 2: ユーザの認証
今回は、ユーザの認証です。
1. モデルの作成
2. ユーザの認証
3. メッセージとコメントの表示
4. Action Cableの利用
ユーザの認証
Action Cable Examplesとの差異:
cookies.signedをcookies.encryptedに変更しました。
・ページの閲覧にはユーザの認証が必要。下記の要領でユーザを認証する。
・localhost:3000/session/newでユーザ名一覧を表示する。
・クリックしたユーザを認証する。
・認証後、localhost:3000/examplesを表示する。
Generate Sessions controller
ユーザ認証に用いるセッションコントローラを生成します。
bin/rails g controller Sessions new
Add session to routes
セッションをルーティングに追加します。
追加するリソースは単数でnewとcreateに限定します。
config/routes.rb
Rails.application.routes.draw do
resource :session, only: %i[new create]
end
ルーティングを確認します。
bin/rails routes
生成したページを確認します。
bin/rails s
open localhost:3000/session/new
Show User.all in sessions#new
sessions#newでユーザ名の一覧を表示します。
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
@users = User.all
end
app/views/sessions/new.html.erb
<h1>Authenticate as one of the following users</h1>
<ul>
<% @users.each do |user| %>
<li><%= link_to user.name, session_url(user_id: user.id), method: :post %></li>
<% end %>
</ul>
bin/rails s
open localhost:3000/session/new
Add Authentication concern
認証に用いるAuthentication concernを追加します。
上記をApplicationControllerにincludeします。
touch app/controllers/concerns/authentication.rb
app/controllers/concerns/authentication.rb
module Authentication
extend ActiveSupport::Concern
private
def authenticate_user(user_id)
if authenticated_user = User.find_by(id: user_id)
cookies.encrypted[:user_id] ||= user_id
@current_user = authenticated_user
else
@current_user = nil
cookies.delete(:user_id)
nil
end
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include Authentication
end
bin/rails s
open localhost:3000/session/new
Call authenticate_user in sessions#create
セッション生成時、authenticate_userを呼び出しユーザを認証します。
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
# ...
def create
authenticate_user(params[:user_id])
redirect_to examples_url
end
ユーザ認証後、examplesページは存在しないため下記のエラーが表示されます。
bin/rails s
open localhost:3000/session/new
=> NameError in SessionsController#create
undefined local variable or method `examples_url' for ...
Railsが表示するウェブブラウザのエラーコンソールで、@current_userとクッキーの中身を確認します。
@current_user
=> #<User id: 1, name: ...
>> cookies.encrypted[:user_id]
=> "1"
Generate Examples controller
認証後に用いるExamplesコントローラを生成します。
bin/rails g controller Examples index
Add examples to routes
Examplesをルーティングに追加します。
追加するリソースは複数でindexに限定します。
config/routes.rb
Rails.application.routes.draw do
resource :session, only: %i[new create]
resources :examples, only: :index
root 'examples#index'
end
bin/rails routes -c examples
認証後に生成したページが表示されることを確認します。
bin/rails s
open localhost:3000
Add ensure_authenticated_user
セッションコントローラを除いて、ユーザ認証を求めるようにします。
ユーザが未認証であれば、認証ページにリダイレクトします。
app/controllers/concerns/authentication.rb
module Authentication
extend ActiveSupport::Concern
included do
before_action :ensure_authenticated_user
end
private
def ensure_authenticated_user
authenticate_user(cookies.encrypted[:user_id]) || redirect_to(new_session_url)
end
def authenticate_user(user_id)
# ...
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
skip_before_action :ensure_authenticated_user, only: %i[new create]
ユーザが未認証/認証済で、意図通りに動くことを確認します。
bin/rails s
open localhost:3000
Show current_user.name in examples#index
現在認証されているユーザの名前をexamples#indexに表示します。
ログアウト用のリンクを用意します。
app/views/examples/index.html.erb
<h1>Action Cable Examples</h1>
<p>
Hello <%= @current_user.name %>
(<%= link_to 'Logout', session_path, method: :delete %>)!
</p>
ユーザ名を確認します。
bin/rails s
open localhost:3000
Add destroy to session routes
ログアウト用のルーティングを追加します。
config/routes.rb
resource :session, only: %i[new create destroy]
bin/rails routes -c session
Call unauthenticate_user in sessions#destroy
sessions#destroyでユーザを未認証にします。
app/controllers/concerns/authentication.rb
def unauthenticate_user
@current_user = nil
cookies.delete(:user_id)
end
app/controllers/sessions_controller.rb
def destroy
unauthenticate_user
redirect_to new_session_url
end
ログイン/ログアウトできることを確認します。
bin/rails s
open localhost:3000
ユーザ認証は、以上になります。
この記事が気に入ったらサポートをしてみませんか?