・ Rails tutorial is the 4th edition ・ This study is the 3rd lap (2nd lap after Chapter 9) ・ The author is a beginner who has done all of Progate.
・ If you read it, you will not understand it. ・ Search and summarize terms that you do not understand (at the bottom of the article, glossary). ・ Dive into what you do not understand. ・ Work on all exercises. ・ Do not copy chords as much as possible.
Authentication system development-The 6th and final chapter 12! The world has four consecutive holidays, but there are no holidays for studying. Let's do it all. Make constant efforts. Click here for today's song. SUPERCAR "PLANET short ver." Good songs won't fade over the years.
2. The named route in Table 12.1 states that _url should be used instead of _path. Why? Think about it. Tip: For the same reason as the account activation exercise (11.1.1.1). → Because you need the complete URL (absolute path).
2. Move to the console and check that the corresponding user object has reset_digest and reset_sent_at (although it is displayed as an error) as a result of sending in the previous exercise. Also, what are the respective values? → There was. following.
>> user = User.find_by(email: "[email protected]")
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "[email protected]"], ["LIMIT", 1]]
=> #<User id: 102, name: "kawa", email: "[email protected]", created_at: "2020-09-17 22:39:47",
updated_at: "2020-09-20 04:23:52", password_digest: "$2a$10$kgv1Loz8fVDaaZvtUMtkZOUBnbCcHZNIBQBrgb18QMj...", remember_digest: nil, admin: false, activation_digest: "$2a$10$bmgQ2XztK7kgePhH8pVDiuKenXFDEl51XktqmfPUwHv...", activated: true, activated_at: "2020-09-17 22:40:33",
reset_digest: "$2a$10$iuW.1GDheym2P5Nkuo7QUu7YjCs1DyooYonE0RY2lck...", reset_sent_at: "2020-09-20 04:23:52">
Let's preview the sent mail from the browser. What kind of information is displayed in the "Date" column? → Date: Sun, 20 Sep 2020 04:49:13 +0000
Let's send a valid email address from the password reset form. Also, look at the Rails server logs to see what the outgoing emails are. → Below
----==_mimepart_5f66df073210_17841d9a2dc334fd
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 7bit
To reset your password click the link below:
https://545f54b8b0d74dfd8bcc26b33cb0f3fe.vfs.cloud9.us-east-2.amazonaws.com/password_resets/TaQ06fMRyqZk-wHJp8fnyw/edit?email=kawa%40kawa.com
This link will expire in two hours.
if you did not request your password to be reset,
please ignore this email and your password will stay as it is.
3. Move to the console and search for the User object whose password was reset in the previous exercise. Once you find the object, let's check the reset_digest and reset_sent_at values that the object has. → Below
reset_digest: "$2a$10$JUgxhUTG.XKFk7BnZqfLHeU8fdUIU/cnMvBGaAs.RCX...",
reset_sent_at: "2020-09-20 04:48:06">
2. Let's confirm that the test turns red when the second CGI.escape in Listing 12.12 is deleted. → It was RED.
2. Let's actually send the new password from the page displayed earlier. What are the results? → Unknown action The action 'update' could not be found for PasswordResetsController
2. Go to the console and find the user object that sent the password reset. Once found, try getting the value of password_digest for that object. Next, enter a valid password from the password reset form and submit it (Fig. 12.13). If the password reset is successful, get the password_digest value again and make sure it is different from the value you got earlier. Tip: You need to get the new value through user.reload. → And when I try to reset the password, "SQLite3 :: BusyException: database is locked: commit transaction" appears. Refer to this article, it worked when I hit ActiveRecord :: Base.connection.execute ("BEGIN TRANSACTION; END;") in the Rails console. .. The result is below. It's different. Before change: \ $ 2a $ 10 $ kgv1Loz8fVDaaZvtUMtkZOUBnbCcHZNIBQBrgb18QMjyvnK.U3vlW After change: \ $ 2a $ 10 $ / lAIMLbkR84Zg0rBkVmcIeWn6u / UBEOaHGrU34rLR8ZMnmcIEomiu
user.rb
def create_reset_digest
self.reset_token = User.new_token
update_columns(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
end
2. Fill in the template in Listing 12.21 and cover the branching (Listing 12.16) that occurs when you reset the expired password with an integration test (response.body in the code in 12.21 is the HTML body of the page. A method that returns everything). There are several ways to test for expiration, but you can use the technique recommended in Listing 12.21 to check for the word "expired" in the body of the response (note that it's not case sensitive). .. → Below (What is / ~ / i? I don't know even if I look it up)
password_resets_test.rb
test "expired token" do
get new_password_reset_path
post password_resets_path,
params: { password_reset: { email: @user.email } }
@user = assigns(:user)
@user.update_attribute(:reset_sent_at, 3.hours.ago)
patch password_reset_path(@user.reset_token),
params: { email: @user.email,
user: { password: "foobar",
password_confirmation: "foobar" } }
assert_response :redirect
follow_redirect!
assert_match /expired/i, response.body
end
3. The policy of not being able to reset the password after 2 hours is a good security method. But there are still ways to make it better. For example, consider a password reset on a public (or shared) computer. Even if you log out and leave your desk, within 2 hours, you can display the password reset form from the computer history and update the password (and the login mechanism is broken through as it is). I will!). To solve this problem, let's add the code in Listing 12.22 and change the digest to nil after successfully resetting the password. → Just enter @ user.update_attribute (: reset_digest, nil).
4. Add a line to List 12.18 and write a test for the previous exercise. Tip: Let's combine the assert_nil method in Listing 9.25 with the user.reload method in Listing 11.33 to directly test the reset_digest attribute. → Only the relevant part is below
password_resets_test.rb
#Valid password and password confirmation
patch password_reset_path(user.reset_token),
params: { email: user.email,
user: { password: "foobaz",
password_confirmation: "foobaz" } }
assert is_logged_in?
assert_nil user.reload.reset_digest
assert_not flash.empty?
assert_redirected_to user
Cut here! !! The reason is the same as the previous chapter! !!
-Modeled with resources as in the previous chapter. -Reset_sent_at is also added to the User model to set an expiration date for the reset link (to use this as the reference time) -Hidden_field_tag retains the email address even after sending once (edit action). -Play an empty string with @ user.errors.add (: password,: blank).
Finally, the development of the authentication system is over. Even if you do so far, you will be familiar with terms such as tokens and digests. Even if you don't understand a little, if you eat and eat all the time, it will be digested and become bloody. Let's do our best. In the next chapter, we will implement the posting function!
⇨ Go to Chapter 13! ⇦ Click here for Chapter 11 Click here for premise and author status for learning
Not this time.
Recommended Posts