心はいつも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
Rubyの<< には3つの用法あり。

先週の#yokohamarbペアプロ画面をみていて

アイキャッチ画像のリサイズ

768 × 1024 pxの写真をアイキャッチに指定して、150pxにリサイズ表 …

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

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

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

静的ページにaboutというページを追加するのですが、rails gを先にするの …

no image
RailsのRoutingいろいろ

コントローラーがAbc アクションがactrionxだとして、 http://y …

民●党批判したら検索順位が落ちたのか?

このブログ、airpucciのドメインも元のwww.airpucci.comに戻 …

no image
Everyday Rails頑張る。3章モデルスペック

テスト書いてからコードの決意。 今のような環境がない時代のプログラマでしたが、自 …

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

6.3.3ユーザー認証、です。 新規ユーザー登録のときは入力で、:passwor …

no image
あんたのrakeは新しいけど古いのが必要なんだよっ!!と怒られた

Mavericksってrubyが2.0になったんですね。 てのはおいといて、 r …

詳解 Objective-C 2.0 第3版 CHAPTER3 継承とクラス

[]多用といいメッセージキーワードといい、やっぱObjective-Cってキモチ …