Authentication

Authentication is the process of verifying the identify of a user. It is handled by Warden, and comes with a basic setup with helpers for authenticating routes.

User model

Once you have set up authentication, you will see that a model was created for storing user's account information. This model is located at app/models/user.rb.

The default columns in the model are username and encrypted_password.

Password encryption

For security, passwords are hashed using the BCrypt encryption algorithm. The encryption mechanism is already built into the user model.

When creating a new user, it is essential that the encrypted password is stored in the database, and not the unencrypted one.

Creating a new user

To create a new user:

user = User.new
user.username = 'admin'
user.password = '123'
user.save

Although this appears to be storing the unencrypted password in the database, the password= instance method will first encrypt the password.

#<User id: 1, username: "admin", encrypted_password: "$2a$10$pnS4ALhE2X5VUu1GuGrS2.c1Zs5Ke6eptwnubIHKyi7...", created_at: "2018-08-27 23:42:26", updated_at: "2018-08-27 23:42:26">

Confirmations

For registering (and numerous other purposes), you might want to require the user to enter some information twice for verification. The user model already comes with this functionality.

For example, if we require the password to be entered twice:

user1 = User.new.with_confirm(:password)
user1.username = 'admin'
user1.password = '123'
user1.save # Fail
user1.errors #=> # ... @messages={:password_confirmation=>["Passwords don't match"]}

user2 = User.new.with_confirm(:password)
user2.username = 'admin'
user2.password = '123'
user2.password_confirmation = '123'
user2.save # Success
#<User id: 1, username: "admin", encrypted_password: "$2a$10$jBtLScCHce2TPj6jvNFMWeAXfgV0rf0QAs/.omqtiIh...", ...>

The confirmation method name will always be <name of field>_confirmation.

You can also pass multiple field symbols to the with_confirm method:

user = User.new.with_confirm(:email, :password)
user.username = 'admin'
user.email = 'admin@test.com'
user.email_confirmation = 'admin@test.com'
user.password = '123'
user.password_confirmation = '123'
user.save # Success

Authentication controller

Unless you used a specific flag during the authentication setup, an authentication controller will have been created.

This controller handles the routes for logging in or authenticating users, logging out users, and what to do when a page requiring authentication is accessed by an unauthenticated user.

Authentication helpers

Three helper methods are defined during the authentication setup. Both are accessible in all controllers.

  • authenticate - Permits an action to be performed if done by an authenticated user. If the user is not authenticated, they will be redirected.

    This is typically placed at the start of a route handler (as seen in this example):

    class ProductController < Eucalypt::Controller(route: '/products')
      helpers ProductHelper if defined? ProductHelper
      
      # ...
      
      post '/:id/delete' do |id|
        authenticate
        product = Product.find id
        product.destroy!
        redirect to '/'
      rescue ActiveRecord::RecordNotFound
        status 404 # Resource not found
        redirect to "/#{id}"
      end
    end
  • current_user - The user object of the currently authenticated user (or nil if no user is authenticated). Since this isn't always an explicit boolean value, it is suggested to use the authenticated? method for conditionals. For example:

    puts Product.all if authenticated? # Good
    puts Product.all if current_user   # Bad
  • authenticated? alias logged_in? - Checks whether or not a user is currently authenticated or logged in. This should be used for conditionals rather than current_user, since it is always an explicit boolean value. This can be used in views for conditional displays.

Last updated