プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Ruby on Rails
  • 【Ruby on Rails】「bcrypt」によるログイン機能の実装
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Ruby on Rails】「bcrypt」によるログイン機能の実装

12.29

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

イメージ図

イメージとしては下記のような設計で作っていくのが基本となるでしょう。実際はdeviseというGemを使うことが多いとは思いますが、基本は同じです。

bcryptとは?

Railsにおいてパスワードを暗号化するために使用するGemになります。なお、Railsをインストールした際にGemfileにはデフォルトでコメントアウトして入っています。

Gemのインストール

Gemfileに下記のようにbcryptというgemがコメントアウトされて入っているのでコメントを削除します。

1
# gem 'bcrypt', '~> 3.1.7' ★コメントを削除する。

bundleします。

1
bundle

ユーザーテーブルの作成

下記コマンドを実行してユーザーテーブルを作成します。

1
rails g model user name:string password_digest:string

password_digest:string

Railsで用意されているhas_secure_passwordメソッドの機能で使用できるもので、暗号化したパスワードを保存しておくカラムでこの名前は固定になります。

has_secure_passwordメソッド

Railsのモデル内にこのメソッド定義しておくことで「password_digest」と言うカラムを用意しておけばそこに自動できにパスワードを保存して暗号化することができます。

セッションコントローラの作成

Railsではログインをすることはイコール「セッションを張ること」と捉えるのでSessionControllerというコントローラーが作成される場合が多いです。(なお、ここでいうセッションは、Web開発でよく使われるサーバで情報をメモリで保管するセッションのことではなく、リソースとしてのセッションで「Webアプリケーションとのやり取り」というのが正しい意味のようです。)

ログインログアウト時の処理(セッション情報の作成や削除等)を行うセッションコントローラを作成します。

1
rails g controller sessions create destroy --skip-template-engine

--skip-template-engineオプション

セッションコントローラはあくまでセッションの作成や削除を行うためこのオプションを指定してviewファイルを作成しないようにします。

ホームコントローラの作成

ログインのトップページであるホームコントローラを作成します。

1
rails g controller home index

ユーザーコントローラの作成

ユーザー登録機能であるユーザーコントローラを作成します。

1
rails g controller users new create me

ユーザーモデルにhas_secure_passwordを設定

1
2
3
class User < ApplicationRecord
  has_secure_password ★記述
end

has_secure_passwordを記述することでUserモデルにpassword属性とpassword_confirmation属性が追加されます。これはユーザー登録フォームでよくある「パスワード」と「確認用パスワード」を入力してもらい二つのパスワードが一致していることを要求する物です。(モデルにバリデーションが自動で追加されます。)saveメソッドを呼び出せば「password_digest」というカラムに暗号化されたパスワードが保存される動作になります。

なお、実際にDBに保存されるのは暗号化されたパスワード(password_digest)だけで、passwordやpassword_confirmation等のカラムは実際のDBには存在しません。

has_secure_passwordでできること一覧

  • passwordを自動で暗号化する。
  • password_confirmation属性が自動で追加され、一致確認のバリデーションを自動で設定します。
  • authenticationメソッドで認証チェックをできます。
  • 最大文字数が72文字のバリデーションが追加される。
  • 「User.create」コマンドでパスワード入力必須バリデーションを追加してくれる。(User.updateは追加されないので注意)

ユーザー登録機能

ユーザーコントローラに下記のようなアクションを実装します。saveメソッドを実行すれば自動的に暗号化パスワードが保存されます。

1
2
3
4
5
6
7
8
9
10
11
12
  def create
    user = User.new(user_params)
    if user.save
      session[:user_id] = user.id
      redirect_to 登録成功後のページ
    else
      redirect_to 登録失敗後のページ, flash: {
        user: user,
        error_messages: user.errors.full_messages
      }
    end
  end

ログイン時はまず認証を行いセッションにログイン中のユーザーIDを格納するのが普通です。

1
session[:user_id] = ユーザーID

認証機能

セッションコントローラに下記のようなメソッドを追加します。ユーザーモデルのauthenticateメソッドによりユーザー名とパスワードが合っているか検証することが可能です。(これも、has_secure_passwordメソッドをモデルに実装することで、ユーザーモデルに自動で組み込まれるメソッドになります。)

1
2
3
4
5
6
7
8
9
  def create
    user = User.find_by(name: params[:session][:name])
    if user && user.authenticate(params[:session][:password])
      session[:user_id] = user.id
      redirect_to ログイン成功後のページ
    else
      render ログイン失敗後のページ
    end
  end

ApplicationControllerの設定

全てのコントローラに共通するコントローラの設定になります。

1
2
3
4
5
6
7
8
9
10
11
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :current_user
 
  private
 
  def current_user
    return unless session[:user_id]
    @current_user = User.find_by(id: session[:user_id])
  end
end

動作としては、ログインしているユーザーがいれば(セッションにデータが入っていれば)インスタンス変数「@current_user」にログインしているユーザーを設定します。もし該当するユーザーがいなければログインしていない物としてnilを返します。

ログイン後にセッション情報を取り出す構文

下記のメソッドを使ってセッションからユーザー情報を取り出します。

1
ユーザーオブジェクト.find_by(id: session[user_id])

ただ、こうしたセッションから情報を取得する処理はどのビューでも使う共通の処理になりやすいので共通化するのが一般的になっています。よくあるのはApplicationController(どのコントローラにも継承させる共通コントローラ)にcurrent_userというヘルパーメソッド(どのビューからも使えるメソッド)を定義して意識せず使えるようにします。

ログアウト機能

該当ユーザーのログインしている状態をログアウトしている状態に変えます。具体的には、セッションの中に含まれているユーザーIDをnil(何もない)状態にすればOKです。下記のような感じでセッションから情報を消します。

1
session.delete(:user_id)

スポンサーリンク
  • 2019 12.29
  • miyabisan2
  • コメントを書く
  • Ruby on Rails
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 05.04

    【Webセキュリティ】ハッシュ関数(digest)、実装方法、パスワード運用について

  2. 2019 12.05

    【Ruby on Rails】「検索機能」の実装(Ransack)

  3. 2019 12.01

    【Rspec】基本的な書き方、タグなど

  4. 2019 12.01

    【Ruby on Rails】モデルのデータを絞り込む便利機能(scopeも)

  5. 2020 03.28

    【Ruby on Rails】「Flashメッセージ」について

  6. 2020 12.26

    【Ruby on Rails】「serialize」や「store」について

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【Ruby on Rails】「rake」について

【Ruby on Rails】「Model Spec(…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • API
  • AWS
  • C++
  • CSS
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Git
  • GitLab
  • GraphQL
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • WebRTC
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー