What are Devise Modules
In my previous blog post I wrote a basic introduction to Devise. Go check that out if you’re not already familiar with installing Devise. In this post I will be diving deeper and exploring the 10 modules that make up Devise.
Lets get started.
How to enable/disable Devise Modules
After you install and generate Devise, your user model will look something like this:
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
devise method allows you to include any of the Devise modules. Inversely, if you want to remove a module then you just need to remove it (or comment it out).
Devise exposes a number of configuration options to allow application developers to customise Devise. When you install Devise it will create a file called
config/initializers/devise.rb where you can add configuration options:
Devise.setup do |config| config.remember_for = 52.weeks config.password_length = 8..24 end
Throughout this post I will talk about the configuration options that different Devise modules provide. All of these options can be applied in the same fashion as the example above.
This module is completely hidden from the application developer. The Devise team haven’t documented it, other than to tell you what it is responsible for:
Registerable is responsible for everything related to registering a new resource (ie user sign up).
This module is responsible for providing the email and password validations. This module is optional, many Devise users choose to write their own email/password validations. If you take a look at the source code for Validatable you can see which validations it will apply.
This module has proved tricky for me in the past while I working on a task to modify user email/password validations. It can take a while to remember that these validations are coming from Devise.
If you are using Validatable, there are two methods that you should be aware of:
email_required?. You can override these methods if you want to modify when validations are applied. For example, if you want email to only be required for users in specific countries.
Lastly, Validatable exposes two options which give you the opportunity to customise the validations.
email_regexp: allows you to modify the regex that is used to validate emails
password_length: allows you to modify the length of the password validation
Alternatively, you can also increase the security of bcrypt without changing the underlying algorithm. Devise provides two configuration options:
pepper: Add a random string to provide a more secure hash
stretches: This increases the amount of time required to brute force the hash. This SO thread provides some explanation. By default Devise sets
stretchesto 11 in production and 1 in development.
This module is responsible for what happens when a user clicks ‘Remember me’. When you enable this module the user will see a ‘Remember me’ checkbox (as shown in the image). When the user checks this box and logs in, an additional cookie is set called
remember_user_token with an expiry time (by default 2 weeks from now).
Normally, when a user closes their session and looses their session cookie, they are forced to login to the application again. However, when they have a
remember_user_token Devise will use that cookie to create a new session for them. The user will get a new session cookie and will not be forced to login again.
Devise keeps the internals of this module well hidden. It is mainly used by Devise internally and does not have many public methods exposed. The only thing that you might want to change is the length of time that the user is remembered for. This can be configured with the a configuration option,
A simple module to understand, Timeoutable is responsible for figuring out whether the users session has expired or not and if so timing out the user.
Timeoutable has one configuration option
timeout_in which allows you to configure how long users sessions will last (without activity from the user).
This module uses a number of fields to track user sign in activity:
sign_in_count: Increases every time a sign in is made
current_sign_in_at: A timestamp updated when the user signs in
last_sign_in_at: Holds timestamp of the previous sign in
current_sign_in_ip: remote IP of the signed in user
last_sign_in_ip: remote IP of user from previous sign in.
Trackable doesn’t have any configuration options. The module’s design is simple, switch it on and you get user tracking.
Personally I haven’t found this module very useful. Typically when a project calls for tracking, the business wants more than just sign in count. However, if you just want some basic user login tracking then Trackable may be a good fit.
This module is responsible for resetting the users password and sending out reset instructions. Recoverable relies on two DB fields:
reset_password_token allows Devise to safely find the user who is resetting their password.
reset_password_send_at tracks when the reset password request is sent. This is required because users only have a limited time in which they can reset their password before the token becomes invalid. You can use the
reset_password_within option to configure the length of time within which the users password must be reset.
Recoverable exposes two methods that are useful to application developers:
reset_password(new_password, new_password_confirmation): Allows you to reset the users password
send_reset_password_instructions: Generates a new reset password token and sends out an email with password reset instruction.
reset_password: is worth taking note of. In the past I’ve had to use this method to reset users passwords outside of the normal Devise flow.
This module handles blocking a user after a certain number of invalid attempts. Lockable has a number of useful configuration options:
maximum_attempts: The number of failed attempts the user is allowed before they are blocked
lock_strategy: Choose which strategy to use for account locking, either:
:failed_attempts: Turn on Devise account locking. Accounts will be locked when the user exceeds the specified number of attempts
:none: Devise will not handle locking. This allows to application developer to handle locking on their own.
unlock_strategy: Choose which strategy to use for unlocking a user, either:
:time: Re-enable the user after a certain period of time
:both: Both of the above strategies
:none: None of the above strategies
unlock_in: The time after which you will unlock a user.
For Lockable to work you will need to have the following lines in your Devise migration:
## Lockable t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts t.string :unlock_token # Only if unlock strategy is :email or :both t.datetime :locked_at
Lockable works by incrementing the number of
failed_attempts so that it can keep track of how many times the user has failed to sign in. Once an account has exceeded the allowed number of failed signups Devise sets
locked_at to record that the account is locked.
This module is responsible for checking whether the user has been confirmed and is allowed to sign in. Confirmable is also responsible for sending out confirmation instructions.
Internally, Confirmable tracks this using the following fields:
## Confirmable t.string :confirmation_token t.datetime :confirmed_at t.datetime :confirmation_sent_at t.string :unconfirmed_email # Only if using reconfirmable
Confirmable has the following configuration options:
confirm_within: Time that conformation token is valid for
reconfirmable: Requires email changes to be re-confirmed
allow_unconfirmed_access_for: Allow the user to access their account before confirming it, for a specified amount of time. After which, the account will be blocked
This module allows you to add Omniauth to Devise. For example, you could allow users to login using their Facebook or Twitter account.
The Devise team have written a fairly comprehensive guide to setting up Omniauth and adding new providers.
These are just the modules that are included with Devise out of the box. There are lots of other gems out there that add extra modules to Devise.
For example, the authy-devise gem allows you to use two-factor auth with Devise. The gem provides a new module called
I hope you found this post useful. Researching this has helped me to understand what all of the different modules in Devise do. I hope I’ve passed some of that learning on to you.