LoginSignup
0
0

More than 3 years have passed since last update.

gem(device等)を使わないログイン機能の実装(rails)

Posted at

 記事投稿の背景

今週はrailsチュートリアルを行い、そこで実装したログイン機能についてまとめ&復習を行なっていきたので記事を執筆しました。

これまで簡単な投稿サイトをrailsで作った経験はあるのですが、その際はgemのdeviceを使ってログイン機能を実装していたのでいい経験になりました。

それでは行ってみましょう!!

 ログインの使用について

ログインの使用についてはEmailとPasswordを用いる、
またサインインはName、Email、Passwordを登録できるとします。

①ユーザー登録機能の実装

 (User)モデルの作成

ユーザーの情報をDBに登録するためにモデルを作って行きましょう。

ターミナル
$rails g model User name:string email:string digest:string

このコマンドにより

user
id integer
name string
Email stirng
created_at datetime
updated_at datetime
password_digest string

上記のようなモデルが作成されているはずです。
ではmigrateしてDBに反映させましょう!!

ターミナル
$rails db:migrate

パスワードを入れるカラムをpassword_digestという名前で登録してますが、これはの後に導入するパスワードのセキュリティ対策のためなのでパスワードを入れるカラム名は必ずpassword_digestで登録をする必要があります

それではパスワードのセキュリティを強化するために最先端のハッシュ関数を導入するためにgemに 'bcrypt'を付け加えてhas_secure_passwordを使えるようにしましょう。

gem
source 'https://rubygems.org'

gem 'rails',          '5.1.6'
gem 'bcrypt',         '3.1.12'     ←追加記入

いつも通りbundle installを実行しましょう。

ターミナル
$ bundle install

これでモデルの設定準備は完了です。

では実際にモデルの設定を行なって行きましょう。

app/models/user.rb
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  validates :email, presence: true, uniqueness: true, length: { maximum: 255 }
  has_secure_password
end

モデルの説明として
validatesに入れている設定として
・nameとemailが登録してなきゃイヤ!!
・『nameは50文字以内』、『emailは225文字以内』にしなきゃダメだかんね!!(ツンデレ風)
と制限を加えております。

また、先ほどパスワードのセキュリティ強化で触れていたhas_secure_password
もここで宣言しており、'password', 'password_confirmation'がUserモデル内で使えるようになっています。(password == password_confirmationにならないといけないというvalidatesが設定されている)

ひとまずこれでモデルの作成は完了したので次はコントローラーの設定に行きましょう!!

他にも正規表現を用いたemailの設定やらcookieを用いたログイン状態の維持などあった気がしますがめんどくさいので省略(やる気があれば記事作りまs...)

(Users)コントローラーの作成

次にコントローラーとユーザー登録画面のviewの生成を行いましょう(この場合newというviewとコントローラーのアクションが追加されます。)

ターミナル
$ rails generate controller Users new

それではコントローラーの設定をして行きましょう。

app/controllers/users_controller.rb
  class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user
      redirect_to @user
    else
      render 'new'
    end
  end

  private

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

上記のコードを説明するとdef newでuser/new.htmlで入力されたユーザー情報がコントローラーに送られてきて、その情報をdef createに渡しております。
渡された情報がvalidatesで弾かれずにdef createで登録可能であればDBにユーザー情報をsaveしてユーザーのマイページに移動させる処理をしております。

またこの時private以下に設定しているストロングパラメータでname,email,password,password_confirmation以外のデータを受け付けない設定となっております。(セキュリティ対策?)

(サインイン:ユーザー登録用)viewの作成

ここではusersコントローラーに登録情報を送るためのviewの設定をしていきたいと思います。

app/views/users/new.html.erb
  <div>
    <%= form_for(@user) do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.email_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Create my account" %>
    <% end %>
  </div>

コードとしては
form forでどのインスタンス変数に情報を送るのか(この場合は@user)を決定して、カラム名を宣言した入力ボックスを作成、submitのメソッドでコントローラーのdef createに情報を送る、最後はendでしめる。

submitする情報としては名前・メール・パスワード・パスワード確認となってます。

②ログイン機能の実装

 (sessions)コントローラーの作成

ログイン、ログアウト用のコントローラーとviewの作成を行いましょう。

ターミナル
$ rails g controller Sessions new

ここで生成されたsession/new.htmlをログイン用のページにします。
それでは次はroutesの設定を行いましょう。

routesの設定

config/routes.rb
Rails.application.routes.draw do
  get    '/signup',  to: 'users#new'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users
end

コードの説明として
1. get '/---'  login&signin用hmtlのurl設定
2. post '/login', to: 'sessions#create'     sessionsコントローラーにcreateのHTTPメソッドの実装
3. delete '/logout', to: 'sessions#destroy'    sessionsコントローラーにdeleteのHTTPメソッドの実装
4. resources :users usersコントローラーにHTTPメソッドを全て実装

となっております。

それではlogin用のviewを作っていきましょう!!

(ログイン用)viewの作成

ログインに必要なemailとpasswordの情報を入力するviewの設定をしていきたいと思います。

app/views/sessions/new.html.erb
<div>
    <%= form_for(:session, url: login_path) do |f| %>

      <%= f.label :email %>
      <%= f.email_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.submit "Log in" %>
    <% end %>
  </div>

サインイン用のviewと同じようにform forを用いて情報を送り、DBに登録があるemailとpasswordなのかを調べるられるようにしています。

(sessions)コントローラーの作成

app/views/sessions/new.html.erb
class SessionsController < ApplicationController

  def new
  end

  def create
##送信されたメールアドレスを使って、データベースからユーザーを取り出しています##
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
#############################################################
      log_in user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out
    redirect_to root_url
  end
end

コードの説明としてdef createでviewから送られてきたlogin情報(emailとpassword)をDB照合してあっていたらユーザーマイページにログイン、なければログイン画面に戻されるというメソッド。
この中で使用されているauthenticateメソッドは、モデルでhas_secure_passwordを宣言していると自動的に使用できるようになり、
入力されたパスワードを暗号化し、DBに登録されているpassword_digestと一致するか検証します。
またdef destroyではログアウトして初期ページに戻すというメソッドを実装しております。

これで基本的なログイン機能の実装は終わりです。

終わり

ここまでの内容はrailstutorialの5〜7章の内容をまとめたもので実際のWEBアプリではセキュリティー関連でさらにいろんな制限が必要になったり、ユーザーが使いやすいようにログイン機能の改善などする必要がかると思いますが基礎編ということで今週はここまでとしておきます。

来週にネタがなければログイン機能後編も上げれたらと思っております。後編作りたくない

0
0
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
0
0