パスワードとかを暗号化する際にBCryptを良さげなので
Rails+MongoDBでの導入方法から使用方法まで
やりたいこと
Rails+MongoDBでパスワードフィールド(RDBでいう属性、カラム)とか
生で保存したくないデータを暗号化したいとき
BCryptとは
認証で使用するパスワードを安全にハッシュ化するアルゴリズム。
SHA256等では暗号化として不足するため(下記参照)、
saltと呼ばれる短いランダムな文字列を末尾に加えて暗号化する。
レインボーテーブル(ハッシュ値に対して総当たりで平文を得ようとする)に対して強力のようです
よくあるHash関数アルゴリズムは(元々高速に計算することを意図していたのもあり)非常に高速に計算が可能であり、総当たり試行されてしまえば、現代のコンピュータスペックをもってすれば一瞬で解読されてしまいます。また、レインボーテーブルと呼ばれる、高速にHashから元の値を類推することが可能なアルゴリズムも存在し、Hash化では不足です。
インストール
Gemfileに下記を追加し、bundle install
でインストールできます
# パスワード暗号化Gem
gem 'bcrypt', '~> 3.1.11'
モデル処理
app/models内の暗号化したいフィールド(属性、カラム)があるモデルについて
下記の様にhas_secure_password
メソッドを使用します。
class Hoge
# has_secure_passwordが存在しない。というエラーが発生したら追加します
include ActiveModel::SecurePassword
# パスワード暗号化
has_secure_password
end
Hogeモデルにpassword_confirmationフィールドが追加され、
validateも自動で追加されます。
authenticateメソッドが使えるようになります
なおRDBの場合、password_digest属性の追加されたことにより
マイグレーションが必要になります。
(MongoDB等のNoSQLの場合不要です)
ViewおよびControllersでの使用方法
View側でpasswordをform_tagで送り、Controllersでドキュメント(行、レコード)を追加することで
こうすることでbcryptがpassword_digestフィールドに暗号化されたパスワードを入れます。
Controllers側では暗号化に関わる処理は特に何もする必要はないです。
以下ユーザ登録フォームでの使用方法例
app/views/userCreate.erb
<h4 class="">ユーザー登録</h4>
<%= form_tag("/user/create") do%>
<p class ="">名前</p>
<input class="" name = "name">
<p class ="">Eメール</p>
<input class="" name = "email">
<p class ="">パスワード</p>
<input type="password" class="" name ="password">
<div class="">
<input type="submit" class="btn btn-primary" value="登録">
</div>
<% end %>
/config/route.rb
post "/user/create" => "user#userCreate"
app/controllers/user_controller.rb
def userSignUp
@user = User.new
end
パスワード認証方法
先ほどは暗号化したパスワードを格納しましたが、
今度はパスワードを画面入力した際など、画面から生のパスワードデータがきたときのControllers側の処理はauthenticateメソッドを利用します。
以下、ログイン画面を想定した使用例です
/app/views/login.erb
<%= form_tag("/user/login") do%>
<p class="">ユーザ名</p>
<input class="w-150" name="name">
<p class="">パスワード</p>
<input type="password" class="" name="password">
<div class="">
<input type="submit" class="btn btn-primary" value="ログイン">
</div>
/config/route.rb
post "/user/login" => "user#userLogin"
app/controllers/user_controller.rb
def userLogin
@user = Hoge.find_by(name: params[:name])
# @user.authenticateで入力されたパスワードを暗号化した後に
# password_digestフィールドと比較
if @user && @user.authenticate(params[:password])
flash[:notice] = "ログインしました"
redirect_to("/Fuga")
else
@errorMessage = "ログインに失敗"
render("/login")
end
end
参照
Railsにおけるパスワードの扱い方(BCrypt)
BCryptのすすめ
どちらもありがとうございます。