記事投稿の背景
今週は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 |
stirng | |
created_at | datetime |
updated_at | datetime |
password_digest | string |
上記のようなモデルが作成されているはずです。
ではmigrateしてDBに反映させましょう!!
$rails db:migrate
パスワードを入れるカラムをpassword_digestという名前で登録してますが、これはの後に導入するパスワードのセキュリティ対策のためなのでパスワードを入れるカラム名は必ずpassword_digestで登録をする必要があります。
それではパスワードのセキュリティを強化するために最先端のハッシュ関数を導入するためにgemに 'bcrypt'を付け加えてhas_secure_passwordを使えるようにしましょう。
source 'https://rubygems.org'
gem 'rails', '5.1.6'
gem 'bcrypt', '3.1.12' ←追加記入
いつも通りbundle installを実行しましょう。
$ bundle install
これでモデルの設定準備は完了です。
では実際にモデルの設定を行なって行きましょう。
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
それではコントローラーの設定をして行きましょう。
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の設定をしていきたいと思います。
<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の設定
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の設定をしていきたいと思います。
<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)コントローラーの作成
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アプリではセキュリティー関連でさらにいろんな制限が必要になったり、ユーザーが使いやすいようにログイン機能の改善などする必要がかると思いますが基礎編ということで今週はここまでとしておきます。
来週にネタがなければログイン機能後編も上げれたらと思っております。後編作りたくない