心はいつもAirPucci (空元気でもいいから)

毎日がPucciを着ているような気分

RailsTutorial4.0を高速で復習する。6.3章。

   


6.3セキュアなパスワードを追加する、です。

パスワードはセキュアであるべきと思いますが、なにをしてセキュアというのでしょうか?
そもそも、userモデルはまだ:nameと:emailだけでパスワードはないよね。

仕様の理解

ユーザーを認証するためにパスワードを使用する->やっぱりuserにパスワードの追加が必要->カラム名はpassword_digest
暗号化してデータベースに保存したい
パスワードの送信は暗号化してる??

6.3.1暗号化されたパスワード、です。
bcrypt-rubyは既にGemに入っているので飛ばします。

テストを書く

TDDが板についてきたでしょうか。パスワードのカラム作る前にテスト書きます。

リスト6.22 Userオブジェクトにpassword_digestカラムがあることを確認するテスト。
spec/models/user_spec.rb

略
  #name属性のデータがある
  it { should respond_to(:name) }
  #email属性のデータがある
  it { should respond_to(:email) }
  #password_digest属性のデータがある
  it { should respond_to(:password_digest) }
  #@userがvalidである
  it { should be_valid }
略
end

テストは失敗します。

1) User
Failure/Error: it { should respond_to(:password_digest) }
expected # to respond to :password_digest

password_digestカラムを作る

rails g migration add_password_digest_to_users password_digest:string

userモデルは既にあるので、変更はやはりmigrtionファイルで行うんですね。

中身がこうなっているmigrationファイルができました。

def change
add_column :users, :password_digest, :string
end

rake dbしておきます。

bundle exec rake db:migrate
bundle exec rake test:prepare

テストはパスするはず。
bundle exec rspec spec/

6.3.2パスワードと確認、です。

パスワード追加して何をするのか

セキュアなというか少なくとも暗号化されたパスワードはモデルに追加できたけど、これで何をするのでしょう?まず、ユーザー登録やログインの時に、パスワードを入力し、パスワードの確認欄に同じ物を入力してもらいます。

よって、要求事項としては、
password属性のほかに、password_confirmation属性が必要。
レコードをデータベースに保存する前に2つの属性が一致するか確認しなければならない。

加えて、実はpassword_confirmation属性は保存する必要はない。ユーザーの入力した:password_confirmationをDBに保存してある:passwordと比較ずればよい。
つまりDBにカラムは不要。モデルは必要だけど、、ってこと。

モデルとDBの不一致だなんて。テスト書いておかないとわかんなくなりそうです。

password_confirmationのテストを書く

リスト6.25 パスワードとパスワードの確認をテストする。
spec/models/user_spec.rb

require 'spec_helper'

describe User do

  before do
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobar", password_confirmation: "foobar")
  end

  subject { @user }
  #name属性のデータがある
  it { should respond_to(:name) }
  #email属性のデータがある
  it { should respond_to(:email) }
  #password_digest属性のデータがDBにある
  it { should respond_to(:password_digest) }
  #password属性のデータがユーザー入力にある
  it { should respond_to(:password) }
  #password_ confirmation属性のデータがユーザー入力にある
  it { should respond_to(:password_confirmation) }
  #@userがvalidである
  it { should be_valid }
略
  describe ":passwordが空のとき" do
    before do
      @user = User.new(name: "Example User", email: "user@example.com", password: " ", password_confirmation: " ")
    end
    #validではないと検証する
    it { should_not be_valid }
  end

  describe ":passwordとpassword_confirmationが一致しないとき" do
    before { @user.password_confirmation = "mismatch" }
    #validではないと検証する
    it 
end

:passwordと:password_confirmationは、User.newハッシュの初期化のときの属性なので、DBにあるカラムではなく、ユーザー入力のときの属性であることがわかるようにコメントに書いておきました。書いておかないとホント、わかんなくなるよー

テストは失敗します。山ほどでました。とりあえずUser.newのところで既に違っているからですね。

user.rbに書くhas_secure_passwordが魔法すぎる

ユーザーの新規登録の時は、
入力で、:passwordと:password_confirmatinをもらって、2つを比較して、一致していたら暗号化して:password_digestに保存する。
ユーザーの認証の時は、
入力で
:passwordをもらって、DBから:password_digestひっぱってきて暗号といて比較して、一致していたら認証とする。
っていうのはわかります。

ハッシュにあるユーザー入力のモデルと、DBのモデルが違うっていうのもわかる。

それをじゃ、つなげないと、、って思います。:passwordと:password_confirmationはどう定義すればよいんだろうか、うーっむ。。。。

実は、この辺りは全てgemに書いたbcrypt-rubyがあれば、あとはモデルにhas_secure_passwordって書けばいいらしい。マジですか!なんなんですかその魔法!

リスト6.26 最初のパスワードテストをパスするようにする。
app/models/user.rb

class User < ActiveRecord::Base
 略
  has_secure_password
end

テストは本当にパスしてしまいました。あんなに丸っとエラーがでていたのに。
:passwordと:password_confirmatinと:password_digest3つどもえのごにょごにょも何も書いていません。

んーーーー
あえて自力で認証を作るぜ!っていう男前なコーナーなのになんだか消化不良。

ま、エラーがなくなったので、いったんコミットしておきます。

このメソッドがあまりに目覚しい働きをするので、この後のテストで赤から青に状態を変えるチュートリアルが逆にやりにくくなってしまいます。そこで、一時的にコメントアウトしておいてください

ガクッときますが、そうしましょう。

次は
6.3.3ユーザー認証
です。

 - テクニカル ,

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

no image
「Follow me」バッジのつけ方。

ブログの横についている「Follow me」バッジ。いろんな方がつけているのを見 …

no image
Google Appsで問い合わせフォームを作りました

とっても簡単でした。Google Appsでこのブログに問い合わせフォームを設置 …

Chromeでの文字化けを対処しました。

WordPressで自作テンプレを作ってみたのはよいものの、困った問題が2つ。 …

実機なしでRetina 3.5インチのスクリーンショットを撮る

iPhoneアプリ公開時に2種類の画像登録が必要です。 1つ目はアイコン。アプリ …

no image
iPhoneのメーラーが真っ黒になってしまった。

iPhoneのメーラーはiPhoneにデフォルトでついているメーラーを使っていま …

no image
RailsTutorial4.0を高速で復習する。5.6章。演習3問目。

5章最後の演習、3問目です。 リスト5.38に示すように、元のヘルパーメソッドに …

WordPressのテンプレートを自分で作ってみました

ブログ更新は久々になりました。この2週間、ずっとこのブログ用にWordPress …

no image
RailsTutorial4.0を高速で復習する。3.5章。つづき。

3.5演習の2もんめをやります。 2.お気付きの方もいると思いますが、リスト3. …

no image
RailsTutorial4.0を高速で復習する。6.2.4章。

6.2.4フォーマットを検証する です。 メールアドレスは文字数制限だけじゃだめ …

教育のためならば、iPadアプリ料金なんて青天井ですわ

今年4月、USでのiPad発売。姪の中学入学祝いにちょうどいいなと思っていたら日 …