LoginSignup
2
3

More than 5 years have passed since last update.

railsのキホンvol.8(ログイン機能)

Last updated at Posted at 2019-03-18

ログイン機能

ログインページを作る

まず、ルーティングとコントローラを設定する。
usersコントローラのlogin_formアクションを定義する。

routes.rb
get "login" => "users/login_form"
users_controller.rb
def login_form
end

ビューでログインフォームを表示する。

login_form.html.erb
<p>メールアドレス</p>
<input name="email" value="<%= @email %>">
<p>パスワード</p>
<input type="password" name="password" value="<%= @password %>">
<input type="submit" value="ログイン">

フィームの送信

次に、フォームのあたいを送信できるようにloginアクションを作る。

routes.rb
post "login" => "users/login"
users_controller.rb
def login
end

ログインフォームの方もform_tagを追加しておく。

login_form.html.erb
#/loginへフォームの値を送信
<%= form_tag("/login") do %>
<p>メールアドレス</p>
<input name="email" value="<%= @email %>">
<p>パスワード</p>
<input type="password" name="password" value="<%= @password %>">
<input type="submit" value="ログイン">
<% end %>

また/loginで被っているが、post,getで異なったルーティングと認識されるので問題ない。

ユーザーを特定

loginアクションで、ユーザーを特定する処理をする。
情報が一致した場合はフラッシュメッセージとともに投稿一覧へ。
しなかった場合はエラーメッセージとともにログインフォームへ、初期値として入力済みのもの。

users_controller.rb
def login
    #ログインフォームで入力されたものが、データベースの情報とあっているか確認する
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
      flash[:notice] = "ログインしました"
      redirect_to("/posts/index")
    else
      @error_message = "メールアドレスまたはパスワードが間違っています"
      @email = params[:email]
      @password = params[:password]
      render("users/login_form")
    end
end

session変数

ページを移動してもユーザー情報を保持するためにsession関数を使う。
session[:キー] = 値
と記述をする。
今回は、ログインに成功した時にユーザー情報を保持しts保持したいので、loginアクションを追加修正する。

users_controller.rb
def login
    #ログインフォームで入力されたものが、データベースの情報とあっているか確認する
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
      session[:user_id] = @user.id
      ...
end

また新規登録時にそのままログイン状態にして、セッション変数で情報を保持する。

user_controller.rb
def create
    @user = User.new(
      name: params[:name],
      email: params[:email],
      image_name: "default_user.jpg",
      password: params[:password]
    )
    if @user.save
      #新規登録に成功すれば、ログイン状態にする
      session[:user_id] = @user.id
      flash[:notice] = "ユーザー登録が完了しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/new")
    end
  end

ログアウト機能

ログアウトする場合はセッションの値をからにする。
セッションの値を変更するときはpostとする。

routes.rb
post "logout" => "users#logout"
users_controller.rb
def logout
  session[:user_id] = nil
  flash[:notice] = "ログアウトしました。"
  redirect_to("/login")
end

ログイン中のユーザーを取得する

before_action

各コントローラの全アクションで共通の処理がある場合に使う。

ユーザー情報は全アクションで使うためapplication_controller.rb で処理を書いておく。
ここでは、set_crrent_userメソッドを定義する。

controllers/application_controller.rb
before_action :set_current_user
def set_current_user
  @current_user = User.find_by(id: session[:user_id])
end

アクセス制限

ログインしていない場合

ログインが必要なページを表示しようとした場合は、フラッシュメッセージとともにログインページに移動する、authenticate_userメソッドを作る。

controllers/application_controller.rb
def authenticate_user
    #ユーザー情報がない場合
    if @current_user == nil
      flash[:notice] = "ログインが必要です"
      redirect_to("/login")
    end
end

onlyを用いて、指定したアクションのみでメソッドを実行する。

users_controller.rb
before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
posts_controller.rb
before_action :authenticate_user

ログインしている場合

ログインしている場合も同様に、アクセス制限のメソッドを作っておく。

controllers/application_controller.rb
def forbid_login_user
    if @current_user
      flash[:notice] = "すでにログインしています"
      redirect_to("/posts/index")
    end
end

対応するアクションに対してメソッドを適応させる。

home_controller.rb
before_action :forbid_login_user,{only: [:top]}
users_controller.rb
before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}

ユーザー編集の制限

自分以外のユーザーの編集をできないように制限をかける。

views/users/show.html.erb
#詳細ページのユーザーidとログインユーザーidが一致している場合は編集ok
<% if @user.id == @current_user.id %>
  <%! linl_to("編集","users/#{@user.id}/edit") %>
<% end %>

次にアクションの方でも制限しておく。
ensure_correct_userアクションを用いる。
ログインしているユーザーと編集したいユーザーが等しくないとき、投稿一覧ページへとリダイレクトさせる。

controllers/users_controller.rb
before_action :ensure_correct_user, {only: [:edit,:update]}
def ensure_correct_user
  if @current_user.id != params[:id].to_i
    flash[:notice] = "権限がありません。"
    redirect_to("/posts/index")
  end
end

to_iメソッド

params[:id]で帰ってくる数値は文字列になっているため、to_iメソッドを使うことによって、数値としてidを取得できる。

続き
https://qiita.com/jonnyjonnyj1397/items/dbc91ac83aea40e868ef

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3