[RUBY] (Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 9]

Premise

・ 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.

Basic policy

・ 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.

Next is Chapter 9, the development of the authentication system, the 4th stage, and the latter half of the login implementation. In Chapter 8, we will switch from a temporary session to a permanent one using cookies. There are a lot of security terms, but let's keep track of them to some extent. There is also a docomo account, so we need to raise security awareness.   Click here for today's BGM. My dead girlfriend "Aki No Hachiouji" I feel the arrival of autumn gradually.

[9.1.1 Memory token and encryption memo and exercise]

Password: Created and managed by the user Token: Created and managed by a computer urlsafe_base64: Methods in the SecureRandom module of the Ruby standard library. Returns a random string of length 22 consisting of any of the characters A–Z, a–z, 0–9, “-”, and “_” (64 types).

Keep in mind the following five permanent session creation policies. ** 1. Generate and use a random character string for the storage token. ** ** ** 2. Set an expiration date when storing tokens in browser cookies. ** ** ** 3. Convert the token to a hash value before storing it in the database. ** ** ** 4. Encrypt the user ID saved in the browser cookies. ** ** ** 5. When you receive a cookie containing a persistent user ID, search the database for that ID and verify that the cookie on the storage token matches the hash value in the database. ** **

  1. Open the console and assign the first user in the database to the variable user. Then let's see if the remember method works fine from that user object. Also, check the difference between remember_token and remember_digest. → Below. The hashed remember_digest is stored.
>> user = User.first
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "[email protected]", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk...", remember_digest: nil>
>> user.remember
   (0.1ms)  begin transaction
  SQL (3.0ms)  UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ?  [["updated_at", "2020-09-13 22:33:06.439353"], ["remember_digest", "$2a$10$IQ/x1avxRSAG281J18FRi.f2icjx8Kac5y8bWua5IDVae.C.Kdwcu"], ["id", 1]]
   (5.9ms)  commit transaction
=> true
>> user.remember_token
=> "aGtKYk5iEjSHFs16uB7xTQ"
>> user.remember_digest
=> "$2a$10$IQ/x1avxRSAG281J18FRi.f2icjx8Kac5y8bWua5IDVae.C.Kdwcu"

2. In Listing 9.3, we have defined new tokens and class methods for digests by explicitly calling the User class. In fact, it's now possible to call it using User.new_token or User.digest, so it's probably the clearest way to define a class method. But in fact, there are two ways to define more "Ruby-correct" class methods. One will be a little confusing and the other will be very confusing. Try running a test suite to make sure that both the slightly confusing implementation of Listing 9.4 and the very confusing implementation of Listing 9.5 work. Tip: Note that self refers to the User "model", or instance of the user object, in the normal context, but in the context of Listing 9.4 and Listing 9.5, self refers to the User "class". This is part of the reason for the incomprehensibleness. → If you write as instructed, both are GREEN. I investigated the writing style that appears here. It seems that the one replaced with the first User → self is called the singular method method, and the one summarized by class << self is called the singular class method. For more information, go to this article. ](Https://magazine.rubyist.net/articles/0046/0046-SingletonClassForBeginners.html)

[9.1.2 Keeping login status Notes and exercises]

permanent method: Expire after 20 years. signed method: Performs both digital signature and encryption processing.

  1. Check your browser's cookie and make sure that the browser after login has remember_token and an encrypted user_id. → It is true that both have increased!

2. Open the console and see if the authenticated? Method in Listing 9.6 works. → OK if you enter the remember_token confirmed in Exercise 1 as an argument.

user = User.first
Abbreviation
user.authenticated?("Exercise 1 remember_token")
=> true

[9.1.3 Notes and exercises for forgetting users]

Forget user = update remember_digest with nil.

  1. Comment out the line you fixed in Listing 9.16 and see the bug caused by the two logged-in tabs. Log out on one tab first, then try logging out again on the other tab. → NoMethodError in SessionsController#destroy undefined method `forget' for nil:NilClass

2. Comment out the line fixed in Listing 9.19 and see the bugs caused by the two logged-in browsers. Try logging out in one browser and restarting the other browser to access the sample application. → Omitted because it is sober

3. Uncomment the commented out part in the code above and check that the test suite changes from red to green. → Yes, GREEN !

[9.1.4 Two inconspicuous bug exercises]

  1. Please check with your browser whether the processing flow of 8.1.4 is working properly. In particular, don't forget to go to a different page after displaying the flash message to see if flash is working well. → Let's try it. If you go to a different page, the flash will go out.

[9.2. [Remember me] checkbox memo and exercise]

A ternary operator has emerged. It seems that you can write an if-else statement in one line. Now you can see the code in Listing 8.21 (although :: isn't quite right yet). So the code below is

python


cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost

When it becomes like this.

python


if cost = ActiveModel::SecurePassword.min_cost
  BCrypt::Engine::MIN_COST
else
  BCrypt::Engine.cost
end

  1. Check the cookies information in your browser and check if the result you intended when you checked [remember me]. → I can go.

2. Open the console and consider an example using the ternary operator (Column 9.2). → Very simple below

>> x = 6
=> 6
>> x % 3 == 0 ? "Multiple of 3" : "Don't"
=> "Multiple of 3"

[9.3.1 Exercise to test the [Remember me] box]

  1. In the integration test in Listing 9.25, I explained that the virtual remember_token attribute cannot be accessed, but in fact, it can be accessed by using a special test method called assigns. To access the instance variables defined in the controller from inside the test, use the assigns method inside the test. Pass the symbol corresponding to the instance variable to this method. For example, if the create action defines an instance variable called @user, you can access the instance variable by writing assigns (: user) inside the test. In the case of the application in this tutorial, the create action of the Sessions controller defined user as a normal local variable (not an instance variable), but if you change this to an instance variable, the user's memory token will be correct in cookies. You will be able to test if it is included. Follow this idea to fill in the shortfalls in Listing 9.27 and Listing 9.28 (marked with? And FILL_IN as a hint) and improve the test in the remember me checkbox. → Set user to @user and log in test as follows.

sessions_controller.rb


def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])
      log_in @user
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      redirect_to @user
    else
      flash.now[:danger] = "Invalid email/password combination"
      render 'new'
    end
end

users_login_test.rb


  test "login with remembering" do
    log_in_as(@user, remember_me: '1')
    assert_equal cookies['remember_token'], assigns(:user).remember_token
  end

This login test cookies ['remember_token'], but initially I tried cookies [: remember_token] and it passed the test. I wondered why, and found out, This article. Is it OK to use symbols now? But the Rails version of the tutorial is old ...

[9.3.2 Exercise to test [Remember me]]

  1. Let's make sure that removing the authenticated? Expression in Listing 9.33 causes the second test in Listing 9.31 to fail (make sure this test tests the correct target). Let's). → It failed at the relevant part.

Chapter 9 Summary

-Persist user id and memory token with cookies method. -Operations related to the database are defined in the User class. The methods used in the Session controller are mainly defined in the Session helper. The former is also used in the latter. -The remember_me function is like a switch that separates whether to keep or delete cookies depending on whether the value is 1 or 0. -Current_user is determined by the state and information of the session or cookie. ・ Since information technology terms were scattered around, they are summarized in the glossary.

This chapter is confusing ... Since it is a part that does not appear on the web page, there is a part where the image cannot be drawn. However, the security part cannot be neglected. Maybe I can do it again after a while.

Well next! Chapter 10! We will implement unimplemented user functions!

Go to Chapter 10! Click here for Chapter 8 Click here for premise and author status for learning

A glossary that somehow captures the image

・ Session hijacking An attack method in which a third party (attacker) who is not a party to the communication hijacks the session by knowing the session ID by some means.

・ Packet sniffer A slang term for LAN analyzers. Hardware or software for monitoring and recording traffic passing over a LAN.

・ Cross-site scripting (XSS) A vulnerability in an application used for a website or an attack that exploits the vulnerability. In particular, cyber attacks that occur by inserting malicious malicious scripts into dynamic sites that can be created by Web viewers (eg, SNS such as Twitter, bulletin boards, etc.) using the vulnerability. ..

・ Digital signature A type of public key cryptography used to mimic the security properties of written handwritten signatures.

・ Salt Random data added to the input of a one-way function when hashing data such as passwords and passphrases. As you can see in the translation note in the text, we strengthen the code with a pinch of salt just in case.

・ Assert_empty Claim that obj.empty is true.

・ Assert_nil obj.nil? Claims to be true.

Recommended Posts

(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 11]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 14]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 12]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 5]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 3]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 8]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 6]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 13]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 9]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 10]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 7]
(Giri) A local government employee in his twenties works on a Rails tutorial [Chapter 2]
(Giri) A local government employee in his twenties works on a Rails tutorial [Introduction]
[Rails Tutorial Chapter 5] Create a layout
[Rails Struggle/Rails Tutorial] What you learned in Rails Tutorial Chapter 6
[Rails Struggle/Rails Tutorial] What you learned in Rails Tutorial Chapter 3
(Ruby on Rails6) Creating data in a table
[Rails tutorial] A memorandum of "Chapter 11 Account Activation"
rails tutorial Chapter 6
rails tutorial Chapter 1
rails tutorial Chapter 5
rails tutorial Chapter 10
rails tutorial Chapter 9
rails tutorial Chapter 8
[Rails Tutorial Chapter 2] What to do when you make a mistake in the column name
Rails Tutorial Chapter 5 Notes
Rails Tutorial Chapter 10 Notes
Rails Tutorial Chapter 3 Notes
Rails Tutorial Chapter 3 Learning
Rails Tutorial Memorandum (Chapter 3, 3.1)
Rails Tutorial Chapter 4 Notes
Rails Tutorial Chapter 4 Learning
Rails Tutorial Chapter 1 Learning
Rails Tutorial Chapter 2 Learning
Rails Tutorial Chapter 8 Notes
Rails Tutorial Memorandum (Chapter 3, 3.3.2)
Difficulties in building a Ruby on Rails environment (Windows 10) (SQLite3)
How to display a graph in Ruby on Rails (LazyHighChart)
Apply CSS to a specific View in Ruby on Rails