Last Updated: February 25, 2016
·
9.795K
· robertomiranda

Secure Tokens From Rails 5 to Rails 4.x and 3.x

Rails 5 introduces (ref rails/rails#18217) a new feature for effortless unique random tokens generation in your models, which can be used for multiple purposes, such as invitations, registrations, password reset emails keys or http token based authentication .

AR::SecureToken uses SecureRandom::base58 to generate a 24-character unique token, keep in mind that the probabilities of collisions are 1 / 58 ** 24, so collisions are highly unlikely. It’s still possible to generate a race condition in the database in the same way that validatesuniquenessof can, so if you’re extremely paranoid you’re encouraged to add a unique index in the database.

If you cannot wait for Rails 5 release you can start today thanks to the has_secure_token gem. SecureRandom::base58 is also back-ported in the gem.

Installation

Add this line to your application's Gemfile:

gem 'has_secure_token'

And then run:

$ bundle

Or install it yourself as:

$ gem install has_secure_token

Lets take a look the code:

Setting your Model

The first step is to run the migration generator in order to add the token key field.

$ rails g migration AddTokenToUsers token:string
=>
   invoke  active_record
   create    db/migrate/20150424010931_add_token_to_users.rb

Then need to run rake db:migrate to update the users table in the database. The next step is to update the model code

# Schema: User(token:string, auth_token:string)
class User < ActiveRecord::Base
  has_secure_token
end

user = User.new
user.save
user.token # => "pX27zsMN2ViQKta1bGfLmVJE"
user.regenerate_token # => true

To use a custom column to store the token key field you can use the column_name option .

# Schema: User(token:string, auth_token:string)
class User < ActiveRecord::Base
  has_secure_token :auth_token
end

user = User.new
user.save
user.auth_token # => "pX27zsMN2ViQKta1bGfLmVJE"
user.regenerate_auth_token # => true

2 Responses
Add your response

Thank you, your article made me write a ticket about potential issues with using Base58 https://github.com/rails/rails/issues/20133

over 1 year ago ·

Thanks!

over 1 year ago ·