心はいつも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

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

  関連記事

iOS developerプログラムに登録しました

iPhoneアプリを初めてリリースしたのは2010年7月です確か。 デベロッパー …

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

9.3.2サンプルのユーザー、です。 Faker gemで、実際にありそうなユー …

no image
MacBookAirで真央ちゃんのテレビ放映を見ました

テレビ持っていないを公言しています。 15年以上使っていたナショナル6型ブラウン …

no image
ToDoの管理方法

東大生はノートがきれいだとか、、 きれいに書いている暇があったら、頭に書いて覚え …

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

9.2認可、です。 自分以外の人が自分のProfileを変更できないようにします …

初めてのRuby2章「配列とハッシュ」

Railsだってgemの一種!ってことで、Rubyの文法からちゃんとやりたいです …

no image
wordpressはじめます

ブログを立ち上げるのは久しぶりです。 以前から、ブログメディアをやりたいと思って …

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

巷にRails4本がなく、Rails3本をRails4でやってみようとしたところ …

twitterと連携した写真のライブラリー

iPhoneを使うようになってから気軽に写真撮影し、そのままtwitter投稿す …

HerokuにRailsアプリをdeployする

Railsプロジェクトというよりも、Railsアプリっていうほうが正んでしょうか …