Rails ログイン/ログアウト/アクセス制限機能について

今回の記事では

  • ログイン機能
  • ログアウト機能
  • ユーザー名の表示
  • アクセス制限機能

について書いていきます

 

 

  • ログイン機能

ログイン機能は長くなるので工程を書いておきます

  • get "login"とpost "login"ルーティングの作成

       ↓

  • users/login_form.html.erbビューを作成

       ↓

  • パスワードカラムを追加

       ↓

  • フォームの送信に関して書く

       ↓

  • usersコントローラに中身を書いていく

       

 

まずルーティングから

get "login" => "users#login_form

post "login" => "users#login"

先頭に付いているgetとpostが違うのあれば名前が一緒でもいいそうです。

 

次にusersフォルダにlogin_form.html.erbファイルを作成します

そこにユーザー情報を送信出来るようにinputなどを書いていくのですがその前にpasswordを追加したいので前回やったようにusersテーブルにpasswordカラムを追加します

ターミナルで↓を書き

rails g migration add_password_to_users

db/migrateフォルダ内の"更新データの日付_add_password_to_users.rb"ファイル内に↓と書きます

def change

add_column :users, :password, :string

end

これでパスワードカラムがDBに追加されました

rails db:migrate

を忘れずに!

 

次はフォームの送信が出来るようにlogin_form.html.erbファイルにメールアドレスや名前等(ここでは省略)に加えてパスワードを追加します

<%= form_tag("/login") do %>

〜各種送信するフォームの中身(email,name等)〜

<p> パスワード</p>

<input type="password" name="password" value="<%= @password %>">

<% end %>

type="password"は入力した文字が黒塗りで見られないようにするもので、value="<%= @password %>"は初期値を表示するためです

@passwordは後でコントローラ内で定義します

 

次はusersコントローラに"login_form"と"login"を定義して、"login"の中身を書いていきます

def login

@user = User.find_by("email: params[:email], password: params[:password]")

 

if @user

session[:user_id] = @user.id

flash[:notice] = "ログインしました"

redirect_to("/posts/index")

else

@error_message = ""

@email = params[:email]

@password = params[:password]

render("users/login_form")

end

 

end

まずフォームから送信された情報をfind_by("〜")で取得します

次に情報が取得出来た後、@userが存在する場合、

session[:キー名]というのはこれに代入した情報を送信し続ける変数です(ここではユーザーの情報を送信することでページを移動しても情報が保持されログイン状態が続くという仕組み)

else以降は@error_messageでエラーメッセージを表示し、@email = params[:…]と@password = params[:…]はビュー内のvalue="〜"で初期値を表示するためのものです

 

  • ログアウト機能

まずはルーティング

post "logout" => "users#logout"

sessionの値を変更する場合もDBの変更の時と同じようにpostを使います

 

ではコントローラを書いていきます

def logout

session[:user_id] = nil

flash[:notice] = "〜"

redirect_to("/login")

end
 session[] = nilにすることで送信する情報を空にすることが出来ます(ターミナルでのrails server起動時にctrl+Cを押して接続をキャンセルするみたいな感じ?)

後はログアウトリンクに忘れずに{method: "post"}を指定してくださいね

 

  • ユーザー名の表示

applicationコントローラ内で定義したアクションをbefore_actionで他のコントローラやビューでも使えるというものなのですが、

このbefore_actionを使ってユーザー名の表示をしていきます

まずapplicationコントローラ内に

before_action :set_current_user

〜省略〜

def set_current_user

@current_user = User.find_by(id:  session[:user_id])

end

を定義します

これは@current_userでログイン中のユーザーidを取得しているという意味です

そしてbefore_action :〜で他のアクションでも使えるようにします

そしてlayout/application.html.erbファイル内のヘッダーリンク部分に

<il>

  <%= link_to(@current_user.name, "/users/#{@current_user.id}") %>

</li>

と書けばログイン中のユーザー名が表示されます

 

  • アクセス制限

これも基本的には

applicationコントローラ内で定義したアクションを各コントローラ内でbefore_actionを使うものになります。

 

例えばログインしていないユーザーがログインしているページに入ろうとした場合に

def authenticate_user

if @current_user == nil

redirect_to("/login")

end

end

と定義しておけば、これをログインして欲しく無いページのアクションに指定しておけば、このアクションが発動されてアクセスが制限されるというわけです

例:usersコントローラ内のedit,updateアクションでこのアクション(authenticate_user)を行いたい場合、usersコントローラ内で

before_action :authenticate_user, {only: [:edit, :update]}

と適用したい任意のアクションをonlyで指定します

 

後はログイン中のユーザーが別のユーザーの編集を出来ないように、(ここではusersコントローラ内でのみ適用させるので)usersコントローラ内で

before_action :ensure_correct_user,

{only: [:edit, :update]}

〜省略〜

def ensure_correct_user

  if @current_user.id !=  params[:id].to_i

   redirect_to("/posts/index")

  end

end

を定義します

ポイントは@current_userが params[:id]で受け取った値と比較する場合に params[:~]は文字列でしか受け取れないので.to_iを使って数値に変換する必要があるところです

 

今日はこれで以上です。

初めて3000文字以上書きましたが時間がかかり疲れました…

いつも1000文字当たり1時間くらいかかるので(今回は2.5時間くらい)なかなか更新するのは大変ですが、良いアウトプットだと思い頑張って続けます💪

 

いつも読んでくださりありがとうございます🙏

 

f:id:takayanagi-prg:20180914194137j:image