パスワードを暗号化しよう
Gemfileを編集しよう
gemとは
gem
gemとは、RubyやRailsでプログラミングをする際に「よく使う機能」をパッケージ化したものです。「検索機能を作るgem」や「暗号化するためのgem」など様々なgemが存在し、Railsにインストールすることで使用することができます。
今回はbcryptという「暗号化するためのgem」を使います。
Gemfile
GemfileGemfile.lockgem
Railsにはインストールしたいgemを記述するGemfileというファイルが存在します。図のように、「gem ‘gemの名前’」と記述します。「rails new」コマンドで生成されたGemfileには既にいくつかのgemが書かれてインストールされています。また、Gemfileの下にあるGemfile.lockというファイルは自動で作成されるファイルなので編集する必要はありません。
gemのバージョン
gem
「gem ‘rails’, ‘5.0.3’」の数字の部分はgemのバージョンを意味しています。図のように「gem ‘gemの名前’, ‘gemのバージョン’」とすることで記述したバージョンのgemをインストールすることが可能です。バージョンを指定しない場合は、最新のgemがインストールされます。
bcryptのインストール
gemGemfilebcryptbundle install
RailsにはGemfileというファイルがあり、インストールするgemが書かれています。今回は右の図のように「gem ‘bcrypt’」という1行を追加します。
Gemfileを編集し、ターミナルで「bundle install」というコマンドを実行すると、書かれたgemをインストールすることができます。
Gemfile
# 指定されたコードを貼り付けてください
gem ‘bcrypt’
■ ターミナルで以下のコマンドを実行してください
bundle install
has_secure_password
has_secure_passwordbcrypt
bcryptをインストールすると、has_secure_passwordというメソッドが使えるようになります。図のようにパスワードを扱うUserモデルにhas_secure_passwordを追加します。こうすることで、ユーザーを保存する際に自動的にパスワードを暗号化してくれます。
user.rb
class User < ApplicationRecord
# has_secure_passwordメソッドを追加してください
has_secure_password
password_digestカラムを追加しよう
複数カラムの変更
マイグレーションファイル
これまでは1つのマイグレーションファイルで1つのカラムを追加してきましたが、複数のカラムを変更することも可能です。例えば、図のようにすることでimage_nameカラムとpasswordカラムを同時に追加することが可能です。今回は、password_digestカラムの追加とpasswordカラムの削除を1つのマイグレーションファイルで行ってみましょう。
マイグレーションファイルの作成
rails g migrationコマンドを用いてマイグレーションファイルを作成しましょう。今回は複数のカラムを変更するため、change_users_columnsというファイル名にしましょう。ファイルを作成したら、まず右の図のようにpassword_digestカラムが追加されるよう、マイグレーションファイルを編集しましょう。
passwordカラムの削除
remove_column
次にpasswordカラムが削除されるよう、左の図のようにマイグレーションファイルを編集しましょう。カラムを削除する場合は、add_columnの代わりにremove_columnを用います。ファイルを編集したら、ターミナルでrails db:migrateを実行し、変更をデータベースに反映させましょう。
■ ターミナルで以下のコマンドを実行してください
rails g migration change_users_columns
■ マイグレーションファイル編集後、ターミナルで以下のコマンドを実行してください
rails db:migrate
change_users_columns.rb
class ChangeUsersColumns < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest, :string
remove_column :users, :password, :string
end
end
passwordとpassword_digest
password_digestカラムに暗号化されたパスワードを保存するためには、今まで通りpasswordに値を代入します。
こうすることで、has_secure_passwordによってpasswordに代入された値が暗号化され、password_digestカラムに保存されます。
このため、既にあるpasswordに関するコードを変更する必要はありません。
■ ターミナルで以下のコマンドを実行してください
rails console
■ コンソールで以下のコードを実行してください
user = User.find_by(id: 1)
user.password = "ninjawanko"
user.password_digest
user.save
暗号化されたパスワードを用いたログイン
authenticateメソッド
authenticateメソッド
has_secure_passwordメソッドを有効にすると、authenticateメソッドを使えるようになります。authenticateメソッドは渡された引数を暗号化し、password_digestの値と一致するかどうかを判定してくれます。
右の図のようにauthenticateメソッドを使って、「送信されたメールアドレスと一致するユーザー」のpassword_digestと、送信されたパスワードが一致するかどうかでログイン処理をします。
users_controller.rb
def login
# メールアドレスのみを用いて、ユーザーを取得するように書き換えてください
@user = User.find_by(email: params[:email])
# if文の条件を&&とauthenticateメソッドを用いて書き換えてください
if @user && @user.authenticate(params[:password])
session[:user_id] = @user.id
flash[:notice] = "ログインしました"
redirect_to("/posts/index")
else
@error_message = "メールアドレスまたはパスワードが間違っています"
@email = params[:email]
@password = params[:password]
render("users/login_form")
end