Rails 7.1 Introduces ActiveRecord::Base::generates_token_for
source link: https://blog.saeloun.com/2023/11/14/rails-7-1-introduces-active-record-generate-token-for/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Rails 7.1 Introduces ActiveRecord::Base::generates_token_for
Nov 14, 2023Prasanth Chaduvula
I'm a React, Javascript & Rails full-stack Software Engineer. I have been working remotely for the past two years in a remote village. Before joining as a Software Engineer I founded kwiq - a hyperlocal delivery startup to deliver things in remote villages.
With ActiveRecord::Base.generates_token_for
we can generate tokens for specific purposes and verify their authenticity.
This feature simplifies the process of generating
and validating tokens, enhancing the security
and user experience of our application. Can be used to implement features like password reset, email confirmation,
and other features that require single-use tokens.
generates_token_for
takes these below arguments:
-
Purpose (Symbol or String) as the first argument, which is used to distinguish between different types of tokens in our application. The purpose helps us categorize and manage tokens for various use cases, such as authentication, email confirmation, password reset, or other custom scenarios. It is typically represented as a symbol or string.
-
expires_in (Duration): Specifies the token’s expiration time, which is the length of time the token remains valid. we can use a duration, such as 1.day, 2.hours, etc. Tokens will automatically expire after the specified duration. By default, tokens do not expire.
-
Block: An optional block that defines how the token data is generated. The block is evaluated in the context of the model instance for which the token is being generated. The block’s return value is embedded in the token as JSON data. When fetching a record using the token, the block is evaluated again in the context of the fetched record, and the two JSON values are compared for validation.
-
Token only gets expires when the duration passed to
expires_in
is completed or the value passed to the block gets updated.
class User < ActiveRecord::Base
validates :name, presence: true
generates_token_for :name_confirmation, expires_in: 24.hours do
name
end
end
user = User.create(name: 'John Doe')
token = user.generate_token_for(:name_confirmation)
User.find_by_token_for(:name_confirmation, token) # => user
user.update!(name: "Sam Smith")
User.find_by_token_for(:name_confirmation, token) # => nil
generate_token_for(purpose)
Generate token on a record by passing the predefined purpose. Return the generated token.
user = User.first
token = user.generate_token_for(:name_confirmation)
find_by_token_for(purpose, token)
Finds a record using a given token for a predefined purpose. Returns nil if the token is invalid or the record was not found.
User.find_by_token_for(:name_confirmation, token)
find_by_token_for!(purpose, token)
Finds a record using a given token for a predefined purpose. Raises ActiveSupport::MessageVerifier::InvalidSignature
if the token is invalid (e.g. expired, bad format, etc). Raises ActiveRecord::RecordNotFound
if the token is valid but the record was not found.
User.find_by_token_for!(:name_confirmation, token)
Generate token with no block
When we dont pass any block which contains the attributes to generates_token_for
. Even after updating the record the token won’t be expired. It only expires once the duration defined in expires_in
is completed.
class User < ActiveRecord::Base
validates :name, presence: true
generates_token_for :name_confirmation, expires_in: 40.seconds
end
user = User.create(name: 'John Doe')
token = user.generate_token_for(:name_confirmation)
User.find_by_token_for(:name_confirmation, token) # => user
user.update!(name: "Sam Smith")
User.find_by_token_for(:name_confirmation, token) # => user
# 40 seconds later...
User.find_by_token_for(:name_confirmation, token) # => nil
Generate token with block
By default, the generate token do not have any expiry and if the value passed in the block gets updated then token will expiry.
class User < ActiveRecord::Base
validates :name, presence: true
generates_token_for :name_confirmation do
name
end
end
user = User.create(name: 'John Doe')
token = user.generate_token_for(:name_confirmation)
User.find_by_token_for(:name_confirmation, token) # => user
user.update!(name: "Sam Smith")
User.find_by_token_for(:name_confirmation, token) # => nil
Generate token with no expiry and no block
By default, the generated token do not have any expiry and without passing any block the token won’t be expired even after updating the attributes. This is useful when we need token with no expiry like auth token or some unique admin tokens.
class User < ActiveRecord::Base
validates :name, presence: true
generates_token_for :auth_token
end
user = User.create(name: 'John Doe')
token = user.generate_token_for(:auth_token)
User.find_by_token_for(:auth_token, token) # => user
user.update!(name: "Sam Smith")
User.find_by_token_for(:auth_token, token) # => user
Share this post!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK