Ruby
Rails
セキュリティ
bcrypt

Railsにおけるパスワードの扱い方(BCrypt)

Rails開発においてbcryptを使用するため少し調べてみました。
筆者の環境はこんな感じです。

Ruby '2.4.1'
Rails '5.1.4'
bcrypt '3.1.11'

BCryptとは

bcrypt(ビークリプト)とはBlowfish暗号に基づいて作られたパスワードハッシュ関数。
bcryptはsaltと呼ばれる短いランダムな文字列を末尾に加えて暗号化するため、レインボーテーブル(ハッシュ値に対して総当たりで平文を得ようとするもの)に対して強いという特徴があります。

インストール方法

Gemfileに記述し、$ bundle installでインストールします。

Gemfile
gem 'bcrypt', '3.1.11'

パスワードのハッシュ化

has_secure_password

セキュアなパスワードの実装には、has_secure_passwordメソッドを使用します。セキュアなパスワードを実装したいモデルで以下のように記述するだけです。

hoge.rb
class Hoge < ApplicationRecord
  has_secure_password
end

こうすることで、Hogeモデルにpassword,password_confirmation属性が追加され(バリデーションも追加される)、authenticateメソッドが使えるようになります。

password_digest属性の追加

ハッシュ化したパスワードですが、has_secure_passwordではデータベース内のpassword_digestという属性に保存できるようになります。(passwordではない点に注意)

そのため、データベースにpassword_digest属性を追加する必要があります。
以下のようにマイグレーションを生成してカラムを追加しましょう。

$ rails generate migration add_password_digest_to_hoges password_digest:string
$ rails db:migrate

ここで、マイグレーション名の末尾をto_hogesにすることでRailsによって自動的にhogesテーブルにカラムを追加するマイグレーションとなります。

Viewの作成

あとはpasswordとpassword_confirmationをフォームで送るだけでbcryptが暗号化してくれるので、そのビューを作成します。以下はフォームの一例です。

app/views/hoges/form.html.erb
<%= form_for(@hoge) do |f| %>

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

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

<% end %>

これでフォームを送信すればpassword_digestに暗号化されたパスワードが入ります。
あとはパスワードを認証するだけです。

authenticateメソッド

パスワードを認証するには、authenticateメソッドを利用します。
実装するのは簡単で、以下のように記述します。

@hoge.authenticate("foobar")

これで、もし@hoge(has_secure_passwordを追加したモデルのオブジェクト)のパスワードがfoobarなら、これはtrueを返します。

参考文献

Ruby on Rails Tutorial 第6章を参考にさせていただきました。

初投稿なので間違い等ございましたらご指摘いただけるとありがたいです。