yutokyokutyo / rebuild_sample_app

https://railstutorial.jp/chapters/static_pages?version=5.0#cha-static_pages
https://rebuildsampleapp.herokuapp.com/
5 stars 0 forks source link

11章 #22

Closed yutokyokutyo closed 7 years ago

yutokyokutyo commented 7 years ago

なんとなくこんなことをやりそう。とオーバービュー&予想...。

img_6413

yutokyokutyo commented 7 years ago

見積もり

yutokyokutyo commented 7 years ago

11.1.1

表 11.2の名前付きルートでは、_pathではなく_urlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: 私達はこれからメールで名前付きルートを使います。

yutokyokutyo commented 7 years ago

11.1.2

  1. コンソールを開き、CGIモジュールのescapeメソッド (リスト 11.15) でメールアドレスの文字列をエスケープできることを確認してみましょう。このメソッドで"Don’t panic!"をエスケープすると、どんな結果になりますか?
[1] pry(main)> CGI.escape('foo@example.com')
=> "foo%40example.com"
[2] pry(main)> CGI.escape("Don'tpabic!")
=> "Don%27tpabic%21"
yutokyokutyo commented 7 years ago

11.1.3

Railsのプレビュー機能を使って、ブラウザから先ほどのメールを表示してみてください。「Date」の欄にはどんな内容が表示されているでしょうか?

Sun, 16 Apr 2017 08:55:32 +0000

yutokyokutyo commented 7 years ago

11.2.1

コンソールを開き、CGIモジュールのescapeメソッド (リスト 11.15) でメールアドレスの文字列をエスケープできることを確認してみましょう。このメソッドで"Don’t panic!"をエスケープすると、どんな結果になりますか?

[1] pry(main)> CGI.escape('foo@example.com')
=> "foo%40example.com"
[2] pry(main)> CGI.escape('Don’t panic!')
=> "Don%E2%80%99t+panic%21"
yutokyokutyo commented 7 years ago
  1. 新しいユーザーを登録したとき、リダイレクト先が適切なURLに変わったことを確認してみましょう。その後、Railsサーバーのログから送信メールの内容を確認してみてください。有効化トークンの値はどうなっていますか?
  Rendering user_mailer/account_activation.html.erb within layouts/mailer
  Rendered user_mailer/account_activation.html.erb within layouts/mailer (1.6ms)
  Rendering user_mailer/account_activation.text.erb within layouts/mailer
  Rendered user_mailer/account_activation.text.erb within layouts/mailer (0.9ms)
UserMailer#account_activation: processed outbound mail in 188.0ms
Sent mail to hogehogehoge@gmail.com (12.2ms)
Date: Mon, 17 Apr 2017 09:32:52 +0900
From: noreply@example.com
To: hogehogehoge@gmail.com
Message-ID: <58f40d34d1890_2a203ffc47541ea080852@PMAC359S.mail>
Subject: Account activation
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="--==_mimepart_58f40d34cf741_2a203ffc47541ea08074b";
 charset=UTF-8
Content-Transfer-Encoding: 7bit

----==_mimepart_58f40d34cf741_2a203ffc47541ea08074b
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Hi hogehogehoge,

Welcome to the Sample App! Click on the link below to activate your account:

https://localhost:3000/account_activations/923QUD9ewl4dIwyAEU4BEg/edit?email=hogehogehoge%40gmail.com

----==_mimepart_58f40d34cf741_2a203ffc47541ea08074b
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style>
      /* Email styles need to be inline */
    </style>
  </head>

  <body>
    <h1>Sample App</h1>

<p>Hi hogehogehoge,</p>

<p>
Welcome to the Sample App! Click on the link below to activate your account:
</p>

<a href="https://localhost:3000/account_activations/923QUD9ewl4dIwyAEU4BEg/edit?email=hogehogehoge%40gmail.com">Activate</a>

  </body>
</html>

----==_mimepart_58f40d34cf741_2a203ffc47541ea08074b--

Redirected to http://localhost:3000/
Completed 302 Found in 865ms (ActiveRecord: 5.3ms)
923QUD9ewl4dIwyAEU4BEg
  1. コンソールを開き、データベース上にユーザーが作成されたことを確認してみましょう。また、このユーザーはデータベース上にはいますが、有効化のステータスがfalseのままになっていることを確認してください。
[3] pry(main)> User.find_by(email: 'hogehogehoge@gmail.com')
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "hogehogehoge@gmail.com"], ["LIMIT", 1]]
=> #<User:0x007f92f3c76ab8
 id: 7,
 name: "hogehogehoge",
 email: "hogehogehoge@gmail.com",
 created_at: Mon, 17 Apr 2017 00:32:52 UTC +00:00,
 updated_at: Mon, 17 Apr 2017 00:32:52 UTC +00:00,
 password_digest: "$2a$10$4hofXjqifhH5H9ZAydVrPeSRh3iniypcRWPjo9bEhV7UGwS.Em/Oi",
 remember_digest: nil,
 admin: false,
 activation_digest: "$2a$10$KghHZ.WcBADAwxI60uWzgOde1/o9TNE7zt809y8oBaltObljXl156",
 activated: false,
 activated_at: nil>
yutokyokutyo commented 7 years ago

user.send("activation_digest") => "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9Ae"

attribute = :activation user.send("#{attribute}_digest") => "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9Ae"

これが...噂のメタプログラミング。

yutokyokutyo commented 7 years ago

11.3.1

コンソール内で新しいユーザーを作成してみてください。新しいユーザーの記憶トークンと有効化トークンはどのような値になっているでしょうか? また、各トークンに対応するダイジェストの値はどうなっているでしょうか?

[9] pry(main)> user = User.new(name: "nekoinu", email: "nekoinu@gmail.com")
=> #<User:0x007f8a1ff57e08
 id: nil,
 name: "nekoinu",
 email: "nekoinu@gmail.com",
 created_at: nil,
 updated_at: nil,
 password_digest: nil,
 remember_digest: nil,
 admin: false,
 activation_digest: nil,
 activated: false,
 activated_at: nil>

nil。 nil じゃないように新しいユーザーを作らないといけなかった?

実際にポチポチして作ってみた。

password_digest: "$2a$10$dDiuDKkhNc3dTO2Wn91Z5e/wdR/g2rtMF.1wf9Rbx.ifSfg05RYLS",
  remember_digest: nil,
  admin: true,
  activation_digest: "$2a$10$.KXMgyGoIgLoxaZ4S2vXNurrcVYnm7zqc7/113cUXuqnPRZIuJCRW",

リスト 11.26で抽象化したauthenticated?メソッドを使って、先ほどの各トークン/ダイジェストの組み合わせで認証が成功することを確認してみましょう。

[3] pry(main)> user.authenticated?(:remember, '')
=> false
[4] pry(main)> user.authenticated?(:remember, 'nil')
=> false
[5] pry(main)> user.authenticated?(:remember, nil)
=> false

nil の場合は認証成功しない..

[9] pry(main)> user.authenticated?(:activation, '6rU1yy2124b8Md5wK4XIfw')
=> true
yutokyokutyo commented 7 years ago

11.3.2

  1. コンソールから、11.2.4で生成したメールに含まれているURLを調べてみてください。URL内のどこに有効化トークンが含まれているでしょうか?

rails console でどうにかしてメールの内容を見て、その中のURLを調べるということだよね..? どうやったらコンソールを使ってメールを送信できるのだろう..でタイムアップ。

  1. 先ほど見つけたURLをブラウザに貼り付けて、そのユーザーの認証に成功し、有効化できることを確認してみましょう。また、有効化ステータスがtrueになっていることをコンソールから確認してみてください。
yutokyokutyo commented 7 years ago

1. について

コンソールというか... サーバーログではないかな?

https://localhost:3000/account_activations/6rU1yy2124b8Md5wK4XIfw/edit?email=hoge@gmail.com6rU1yy2124b8Md5wK4XIfw が有効化トークン

2. について

image

https だと接続できなかったけど http にしたら接続できた。 trueになってる!

activation_digest: "$2a$10$pVEP3M.dS/Vm1AQLl8yUCOuG6H/uBEIlxD0kF2xOLIGuaNa/FodAy",
 activated: true,
yutokyokutyo commented 7 years ago

テストが落ちてるぞぅ?

% rails t                                                                                                                  (git)-[account-activation]
Running via Spring preloader in process 70819
Started with run options --seed 11623

ERROR["test_login_with_remembering", UsersLoginTest, 1.4665467829981935]
 test_login_with_remembering#UsersLoginTest (1.47s)
NoMethodError:         NoMethodError: undefined method `remember_token' for nil:NilClass
            test/integration/users_login_test.rb:43:in `block in <class:UsersLoginTest>'

  43/43: [=======================================================================================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.32083s
43 tests, 189 assertions, 0 failures, 1 errors, 0 skips
yutokyokutyo commented 7 years ago

bindingpry してみた。

From: /Users/y.kondo/project/workspace/rebuild_sample_app/test/integration/users_login_test.rb @ line 44 UsersLoginTest#test_login_with_remembering:

    41: test "login with remembering" do
    42:   log_in_as(@user, remember_me: '1')
    43:   binding.pry
 => 44:   assert_equal cookies['remember_token'], assigns(:user).remember_token
    45: end

[1] pry(#<UsersLoginTest>)> cookies['remember_token']
=> "PY0hP-QGq-jDDSSN6JMCmw"
[2] pry(#<UsersLoginTest>)> assigns(:user).remember_token
NoMethodError: undefined method `remember_token' for nil:NilClass
from (pry):2:in `block in <class:UsersLoginTest>'

assigns(:user).remember_token 氏が犯人

yutokyokutyo commented 7 years ago
[5] pry(#<UsersLoginTest>)> assigns(:user)
=> nil

仮説: アサインに失敗しているのでは?

yutokyokutyo commented 7 years ago

assingnsのおさらい

yutokyokutyo commented 7 years ago
login GET    /login(.:format)                        sessions#new
                        POST   /login(.:format)                        sessions#create

session_controllerですな。

https://github.com/yutokyokutyo/rebuild_sample_app/commit/15e0c1d117c435161915eb4c94b58171339056d0

怪しい。

仮説: assings はインスタンス変数にのみアクセスできる。しかし @user というインスタンス変数を user なるローカル変数に書き換えてしまったことで assings がアクセスできなくなってしまった?

yutokyokutyo commented 7 years ago

検証方法

user を @user に置き換える。

検証結果

% rails t                                                                                                                  (git)-[account-activation]
Running via Spring preloader in process 89694
Started with run options --seed 28240

  43/41: [==================================================================================================      ] 95% Time: 00:00:03,  ETA: 00:00:00
Frame number: 0/29

From: /Users/y.kondo/project/workspace/rebuild_sample_app/test/integration/users_login_test.rb @ line 44 UsersLoginTest#test_login_with_remembering:

    41: test "login with remembering" do
    42:   log_in_as(@user, remember_me: '1')
    43:   binding.pry
 => 44:   assert_equal cookies['remember_token'], assigns(:user).remember_token
    45: end

[1] pry(#<UsersLoginTest>)> assigns(:user)
=> #<User:0x007f9a5a092878
 id: 762146111,
 name: "Michael Example",
 email: "michael@example.com",
 created_at: Fri, 21 Apr 2017 03:00:54 UTC +00:00,
 updated_at: Fri, 21 Apr 2017 03:00:58 UTC +00:00,
 password_digest: "$2a$04$RWvZ1NuFq8s6iR3t9k1a/uSdAt/vlIopzEB.F8utVP.MiO3gXvc/m",
 remember_digest: "$2a$04$edgO8/yZcHAYdTiu4cPkCeUAtZZ/fAMVurhuXoj2VwzsB2gSAlgfa",
 admin: true,
 activation_digest: nil,
 activated: true,
 activated_at: Fri, 21 Apr 2017 03:00:54 UTC +00:00>
[2] pry(#<UsersLoginTest>)> assigns(:user).remember_token
=> "cpd4EB0bGaI9zkcNqMxYkw"
[3] pry(#<UsersLoginTest>)>
  43/43: [=======================================================================================================] 100% Time: 00:00:21, Time: 00:00:21

Finished in 21.99878s
43 tests, 190 assertions, 0 failures, 0 errors, 0 skips

そのとおりだた!

yutokyokutyo commented 7 years ago

なにゆえチュートリアルでは user になっているのだろう...? https://railstutorial.jp/chapters/account_activation?version=5.0#code-preventing_unactivated_logins

一次情報も同様だ。 https://www.railstutorial.org/book/account_activation#code-preventing_unactivated_logins

yutokyokutyo commented 7 years ago

この問題はひとまず後で考えよう...。

yutokyokutyo commented 7 years ago

上の問題は独立して新たに issue をたてた。 11章完!長かった..。10日間くらいやってたかも。