Chapter 7 - Advanced login

Introduction

Although the basic login functions in Chapter 6 are probably already good enough for government work, there's one feature we'd like to add that turns out to be both challenging and instructive: a "remember me" box that, when checked, allows RailsSpace to remember the login status of its users. Like basic login, this involves using the session to maintain user state, but it also requires using browser cookies (and the methods Rails has for manipulating them). Cookies represent a more permanent way of maintaining state than the session, allowing us to remember users even after they've closed their browsers.

Implementing the "remember me" feature is surprisingly complicated, producing rather bloated and ugly code. Before tackling this code bloat, we'll dig even deeper into Rails tests, including extensive testing of our cookie functions and an example of integration testing (mentioned briefly in Chapter 5). Once our test suite is complete, we'll refactor the authentication functions with a vengeance, producing a surprisingly compact and elegant login action.

Table of Contents

  • 7.1 So you say you want to be remembered? 181
    • 7.1.1 A "remember me" box 182
    • 7.1.2 A "remember me" attribute 184
    • 7.1.3 The "remember me" cookie 186
  • 7.2 Actually remembering the user 192
    • 7.2.1 An authorization cookie 193
    • 7.2.2 Remembering that we remembered 195
    • 7.2.3 Updating logout 197
    • 7.2.4 A more secure cookie 199
    • 7.2.5 The finished (?) functions 201
  • 7.3 "Remember me" tests 203
    • 7.3.1 Updated login tests 203
    • 7.3.2 Updated logout test 209
  • 7.4 Advanced tests: Integration testing 209
    • 7.4.1 Testing cookie remembering: The first cut 210
    • 7.4.2 Testing the test: A cautionary tale 212
    • 7.4.3 Some reflections on Rails testing 214
  • 7.5 Refactoring redux 215
    • 7.5.1 Refactoring remember 216
    • 7.5.2 Refactoring forget 218
    • 7.5.3 Just two more bits of polish 219
    • 7.5.4 The fully refactored login function 222
    • 7.5.5 Some parting thoughts 223

Source Code

Errata

As of the first printing, these are the known corrections:

  1. p.201. Listing 7.17 has a stray line return:
          user.authorization_token = Digest::SHA1.hexdigest(
                                       "#{user.screen_name}:
                                        #{user.password}")
    should be
          user.authorization_token = Digest::SHA1.hexdigest(
                                       "#{user.screen_name}:#{user.password}")
  2. p. 203. Section 7.3. The fourth sentence should read: "Finally, we'll test the check_authorization filter to make sure that user who log out, close their browsers, and return to the site are NOT automatically logged back in."
  3. p. 221. Listing 7.40. There's an extra space in user.forget! (cookies); i.e., it should just be user.forget!(cookies).