LoginSignup
127
134

More than 5 years have passed since last update.

Railsでパスワードの取り扱い(bcrypt 3.1.7以上)

Posted at

登録

パスワードの暗号化で便利な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以上だと動きが異なっているので新しいほうの設定を入れます。

マイグレーションファイルで以下の項目を入れる。

新規は以下

migrate/yyyymmddhhmmss_create_members.rb
class CreateMembers < ActiveRecord::Migration
  def change
    create_table :members do |t|
      t.string :password_digest, null: false
    end
  end
end

追加は以下

migrate/yyyymmddhhmmss_update_members.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration
  def change
    add_column :users, :password_digest, :string
  end
end

「password_digest」というカラムがあれば自動的によしなにしてくれます。

「strong parameters」の変更

rails4.0以上だと必要な「strong parameters」の追加。
こちらは勝手にはやってくれないので、設定を追加します。

app/controllers/members_controller.rb
private
  def member_params
    params.require(:member).permit(:login_name, :email, :password, :password_confirmation)    end

ビューの作成

以下のように「password」と「password_confirmation」の
項目でFormの値を送ります。

app/views/members/login.html.erb
<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を有効にするには以下の行を入れます。

app/models/member.rb
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でログ引用のタグを作っています。

app/views/members/login.html.erb

<%= 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

app/controllers/members_controller.rb
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のオブジェクトを返します。

この後にセッション処理などをすれば無事ログイン処理は完了です。

127
134
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
127
134