ここまで作った TweetApp では、パスワードが普通の文字列として保存されている。
しかし、このままではPCを覗き見られたり、ハッキングでデータが盗まれた場合、そのパスワードを使って、他人のアカウントに不正にログインできてしまう。
そのため、パスワードは安全性の高い取り扱いをする必要がある。
安全性の高いパスワードとは?
安全性の高いパスワードとは、
万が一パスワードを覗き見られたり、データが盗まれても、パスワードの内容がわからない状態
→ ハッシュ化することで安全性を高めることができる
Gemfileを編集する
Rails でパスワードをハッシュ化する際は、gem(ジェム)というツールを必要とする
gemとは
gemとは、RubyやRailsでプログラミングをする際に「よく使う機能」をパッケージ化したもの
「検索機能を作るgem」や「ハッシュ化するgem」など様々なgemが存在し、Railsにインストールすることで使用できる。
今回はbcryptという「ハッシュ化するgem」を使う。
Gemfile
Railsにはインストールしたいgemを記述するGemfileというファイルが存在する
《Gemfile》
gem ‘rails’, ‘5.0.3’
gem ‘puma’,’3.6.2′
- 「gem ‘gemの名前’」と記述する
- 「rails new」コマンドで生成されたGemfileには既にいくつかのgemが書かれてインストールされている
- Gemfileの下にあるGemfile.lockというファイルは自動で作成されるファイルなので編集する必要はない
- 「gem ‘gemの名前’, ‘gemのバージョン’」とすることで記述したバージョンのgemをインストールすることが可能
- バージョンを指定しない場合は、最新のgemがインストールされる
bcryptのインストール
RailsにはGemfileというファイルがあり、インストールするgemが書かれている
《Gemfile》
gem ‘bcrypt’
《ターミナル》
$ bundle install
- Gemfileを編集(「gem ‘bcrypt’」という1行を追加)
- ターミナルで「bundle install」というコマンドを実行する
パスワードのハッシュ化
bcryptをインストールすると、has_secure_passwordというメソッドが使えるようになる。
パスワードを扱うUserモデルにhas_secure_passwordを追加します。
そうすれば、ユーザーを保存する際に自動的にパスワードをハッシュ化してくれる。
《user.rb》
class User < Application
has_secure_password
password_digestカラムを追加する
has_secure_password メソッドは、パスワードを安全のために password カラムには保存せず、ハッシュ化されたパスワードのみ password_digest カラムに保存する。
【やること】
⚫︎現在 users テーブルに password_digest カラムが存在していないので追加する。
⚫︎password カラムは必要なくなるので、消す
複数カラムの変更
これまでは1つのマイグレーションファイルで1つのカラムを追加してきたが、複数のカラムを変更することも可能。
《add_column_users.rb》
def change
add_column :users, :image_name, :string
add_column :users, :password, :string
end
- 例えば、上記のようにすることでimage_nameカラムとpasswordカラムを同時に追加することが可能
マイグレーションファイルの作成
STEP.1 マイグレーションファイルを作成する
《ターミナル》
$ rails g migration change_users_column
今回は複数のカラムを変更するため、このファイル名にする。
STEP.2 password_digestカラムが追加されるように、マイグレーションファイルを編集する
《マイグレーションファイル》
def change
add_column :users, :password_digest, :string
end
STEP.3 passwordカラムを削除
《マイグレーションファイル》
def change
add_column :users, :password_digest, :string
remove_column :users, :password, :string
end
- カラムを削除する場合は、add_columnの代わりにremove_columnを用いる
STEP.4 rails db:migrateをターミナルで実行し、変更をデータベースに反映させる
passwordカラム
password_digestカラムにハッシュ化されたパスワードを保存するためには、今まで通りpasswordに値を代入する。
こうすることで、has_secure_passwordによってpasswordに代入された値がハッシュ化され、password_digestカラムに保存される。
このため、既にあるpasswordに関するコードを変更する必要はない
テスト方法
《ターミナル》
rails console コンソールを起動
user = User.find_by(id: 1) ←変数userにidが1のユーザーを代入
user.password = “ninjawanko” ←任意のパスワードを代入
user.password_digest ←ハッシュ化されたパスワードが取得できることを確認
user.save ←変更を保存
ハッシュ化されたパスワードを用いたログイン
現在は password カラムの値を用いてログインするようになっているので、 password_digest カラムの値を用いてログインできるようにする。
現状のloginアクションでは、「フォームに入力されたメールアドレスとパスワードに一致するユーザーが存在すればログイン」となっているが、以下のステップでログインできるようにする
STEP.1 フォームに入力されたメールアドレスに一致するユーザーを取得する
STEP.2 フォームに入力されたパスワードと、取得したユーザーのパスワードが一致するか判定する
authenticateメソッド
has_secure_passwordメソッドを有効にすると、authenticateメソッドを使えるようになる。
authenticateメソッドは渡された引数をハッシュ化し、password_digestの値と一致するかどうかを判定する
【例】
《コントローラ》
@user.authenticate(“yakkuru@mononoke.com”)
| |
| ←password_digest | ←ハッシュ化
↓ ↓
☆⚫︎△… ←一致するか調べる→ ☆⚫︎△…
《users_controller.rb》
def login
@user = User.find_by(email: params[:email]) ←送信されたメールアドレスを取得
if @user && @user.authenticate(params[:password])
- ↑「送信されたメールアドレスと一致するユーザー」のpassword_digestと、送信されたパスワードが一致するかどうかでログイン処理をする
- リスト
def login
@user = User.find_by(email: params[:email])
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
end
コメント