Rails Tutorial 6章 パスワード編

セキュアなパスワードを追加する

手順
1、パスワードの入力、送信
2、ハッシュ化し、DBに保存
3、DB内のハッシュ化された値との比較

・ハッシュ化とは...
  ハッシュ関数をつかって不可逆なデータに変換


ハッシュ化されたパスワード

これだけ

app/models/user.rb
class User < ApplicationRecord
 .
 .
 has_secure_password
end


has_secure_passwordを追加することによって
・ハッシュ化したパスワードをDB内の password_digest という属性に保存できる
・仮想的な属性( password, password_confirmation ) が使えるようになる。また、存在値と値が一致するかのバリデーションが追加される
・authenticatedメソッドが使えるようになる

has_secure_password を使うためには、DBに password_digestが存在していなければならない

そこで、

$ rails g migration add_password_digest_to_users passsword_digest:string

上記のコード、末尾を to_users にすることによってRailsが自動的にusersテーブルにカラムを追加するマイグレーションファイルを作成する。

できたのが、これ

db/migrate/[timestamp]_add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :password_digest, :string
  end
end

んで、

$ rails db:migrate

また、has_secure_password でパスワードをハッシュ化するためには bcrypt っていうのが必要

Gemfileに追記、インストール

gem 'bcrypt',         '3.1.12'
$ bundle install


これで、has_secure_password が使えるようになった。


セキュアなパスワードの完全な実装

存在性バリデーションと最小文字数

validates :password, presence: true, length: { minimum: 6 }


ユーザーの作成と認証

>> User.create(name: "Michael Hartl", email: "mhartl@example.com",
?>             password: "foobar", password_confirmation: "foobar")

結果、

>> user = User.find_by(email: "mhartl@example.com")
>> user.password_digest
=> "$2a$10$xxucoRlMp06RLJSfWpZ8hO8Dt9AZXlGRi3usP3njQg3yOcVFzb6oK"

authenticatedメソッドで、因数に渡された値をハッシュ化した値と、DB内のpassword_digestカラムの値を比較

>> user.authenticate("not_the_right_password")
false
>> user.authenticate("foobaz")
false

正しい値を与えると、そのユーザーオブジェクトを返す

>> user.authenticate("foobar")
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com",
created_at: "2016-05-23 20:36:46", updated_at: "2016-05-23 20:36:46",
password_digest: "$2a$10$xxucoRlMp06RLJSfWpZ8hO8Dt9AZXlGRi3usP3njQg3...">

ちなみに、 !! でそのオブジェクトが対応する論理値を返す

>> !!user.authenticate("foobar")
=> true