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
Written by Roberto Miranda
Related protips
2 Responses
Thank you, your article made me write a ticket about potential issues with using Base58 https://github.com/rails/rails/issues/20133
Thanks!