登録
パスワードの暗号化で便利なGemのbcrypt。
Railsでの取り扱い
「password」と「password_confirmation」という項目をフォームで送ると、bcryptが勝手に暗号化して、「password_digest」というカラムに暗号化したデータを入れてくれます。
取り出しも楽なので非常に重宝します。
また、has_secure_passwordというメソッドをつかいますが、こちらで以下が行われます。
- modelに「password」、「password_confirmation」属性の追加
- 「password」、「password_confirmation」のvalidationの追加(値の空白や不一致のチェック)
- authoricateメソッドの追加
Gemファイルでbcryptを有効にする
$ vi Gemfile
-------------------------------
gem 'bcrypt', '~> 3.1.7'
-------------------------------
$ bundle install
3.1.7以上だと動きが異なっているので新しいほうの設定を入れます。
マイグレーションファイルで以下の項目を入れる。
新規は以下
class CreateMembers < ActiveRecord::Migration
def change
create_table :members do |t|
t.string :password_digest, null: false
end
end
end
追加は以下
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
「password_digest」というカラムがあれば自動的によしなにしてくれます。
##「strong parameters」の変更
rails4.0以上だと必要な「strong parameters」の追加。
こちらは勝手にはやってくれないので、設定を追加します。
private
def member_params
params.require(:member).permit(:login_name, :email, :password, :password_confirmation) end
ビューの作成
以下のように「password」と「password_confirmation」の
項目でFormの値を送ります。
<div class="field">
<%= f.label :password, "パスワード" %><br>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation, "パスワード再入力" %><br>
<%= f.password_field :password_confirmation %>
</div>
コントローラーの変更
bcrypt-rubyで自動的にdigestを有効にするには以下の行を入れます。
class Member < ActiveRecord::Base
has_secure_password
end
※attr_accessorとかは入れない!!
※validatesや「password」と「password_confirmation」の一致のチェックは自動的にしてくれる。
「attr_accessor」とか入れると、その段階でpasswordの値が空になり以前のバージョンの利用方法だとはまります。
「Password can’t be blank」とかのエラーが出てしまうので、その場合はそちらを修正します。
ログイン
ログイン用のview
ログ引用のviewを以下に表示します。
form_tagでログ引用のタグを作っています。
<%= form_tag('/members/logintmp') do %>
<%= text_field_tag 'login_name', nil, class: 'loginbox-username' %>
<%= password_field_tag 'password', nil, class: 'loginbox-password' %>
<%= submit_tag 'Login', class: 'button button-green' %>
<% end %>
ログイン用のcontroller
def login
member = Member.find_by_login_name params[:login_name]
if member && member.authenticate(params[:password])
render :text => "Login OK"
else
render :text => "Login NG"
end
end
「member = Member.find_by_login_name params[:login_name]」の行では、ログインIDがあっていればmemberのオブジェクトを返します。
間違っていればFalseを返します。
「member.authenticate(params[:password])」のメソッドではそもそもログインIDがNGのときはnilを返します。
ログインIDがあっていてパスワードがあっていればmemberのオブジェクトを返します。
この後にセッション処理などをすれば無事ログイン処理は完了です。