Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungI audited my own ML linter and had to withdraw its best evidence(21.09.2026 um 22:54 Uhr)
Sichere ProgrammierungQuantum Result Validation for Distributed Computing Systems(21.09.2026 um 22:54 Uhr)
Sichere ProgrammierungJWT Authentication and Role-Based Access Control in LocalHands(21.09.2026 um 22:56 Uhr)
Sichere ProgrammierungStochastic Parrot or Alien Mind?(21.09.2026 um 22:56 Uhr)
Sichere ProgrammierungBuilding AI for the Physical World Is a Different Engineering Problem(21.09.2026 um 22:58 Uhr)
Sichere ProgrammierungI audited my own ML linter and had to withdraw its best evidence(21.09.2026 um 22:54 Uhr)
Sichere ProgrammierungQuantum Result Validation for Distributed Computing Systems(21.09.2026 um 22:54 Uhr)
Sichere ProgrammierungJWT Authentication and Role-Based Access Control in LocalHands(21.09.2026 um 22:56 Uhr)
Sichere ProgrammierungStochastic Parrot or Alien Mind?(21.09.2026 um 22:56 Uhr)
Sichere ProgrammierungBuilding AI for the Physical World Is a Different Engineering Problem(21.09.2026 um 22:58 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Rails 8 authentication - password reset mechanics

Following on from this earlier post documenting the implementation process of Rails 8 generated authentication served via API to a React front end, where I did not implement or discuss in detail password reset, this post looks into the…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Following on from this earlier post documenting the implementation process of Rails 8 generated authentication served via API to a React front end, where I did not implement or discuss in detail password reset, this post looks into the Rails 8 password reset mechanism in more detail.



Rails 8 auth gives us a fully signed, expirable, purpose-limited reset token system, without us having to write a single line of token logic ourselves, thank you the Rails team 👏.












🔑 ✉️ The password reset stages in Rails 8 auth:



➡️  Password reset button on the login form routes to PasswordController #new and renders the new.html.erb template, containing an email input form and an 'email password reset instructions' button.



➡️  new form submits to PasswordsController #create, finds db User record from the email param, creates a Mailer Job by calling deliver_later on PasswordsMailer.reset(user).



➡️  Job emails the mailers/reset.html.erb mailer to the user, which contains a link, the URL of which is embedded with a unique token generated from the users id by the @user.password_reset_token call in the reset mailer.



➡️  user clicks the link containing token param, routes to PasswordsController #edit, renders the edit.thml.erb template, which contains a form with new password and password_confirmation fields. #edit action also calls the #set_user_from_token (courtesy of a before_action for #edit & #update) method with the token param, which decrypts & validates the token and sets @user.



➡️  submission of the form in the edit password template, with the token again passed as a param, calls the PasswordController #update action which if #set_user_from_token, courtesy again of before_action, decrypts, validates and sets to a valid @user then updates the user model record with the new password. Password update is then completed, user routed back to the new_session_path for login.












Token Magic



Token generation and decoding are the core of this flow. Here’s how it works behind the scenes.









🔏 How is the token created?:




  • The token is created by this value passed to the url helper within the reset mailer's link_to:




@user.password_reset_token






#password_reset_token is syntactic sugar for #generate_token_for(:password_reset). This code is from the ActiveRecord::Tokens module which from Rails 8 is included in ActiveRecord::Base. This includes the ability to both generate signed, expirable, purpose-scoped tokens, as well as to securely verify and decode them (itself utilising ActiveSupport::MessageVerifier as the cryptographic engine). As a result, methods like user.password_reset_token and user.find_by_password_reset_token!(_token_) are available out of the box. See final section for in depth discussion of these methods.



The url in the link_to in the reset mailer:




<%= link_to "this password reset page", edit_password_url(@user.password_reset_token) %>






generates a URL like /passwords/:token/edit(.:format) due to this route declaration




resources :passwords, param: :token`






This sets up a route pattern where :token replaces the usual :id, so the generated URL includes the generated reset token in place of :token.









🧩 What does the actual token look like?:



The actual token generated will be a variation of this two part string, -- ;




eyJfcmFpbHMiOnsiZGF0YSI6WzYsIlNJdDV5RzIuU3UiXSwiZXhwIjoiMjAyNS0wNi0wNlQyMDo0MjoxNS4xMjFaIiwicHVyIjoiVXNlclxucGFzc3dvcmRfcmVzZXRcbjkwMCJ9fQ==--4d759ab766988553b56740f7ad1386d05a1e5410







1st part – the payload


The payload will be a Base64 encoded representation of a JSON has like the below:




{
_rails: {
data: [user.id, user.class.signed_id_verifier.verifier_name], # usually [6, "SomeInternalSalt"]
exp: 15.minutes.from_now.utc.iso8601, # e.g. "2025-06-06T20:42:15.121Z"
pur: "User\npassword_reset\n900" # class name, purpose, expiry in seconds
}
}







2nd part - the HMAC digest:


HMAC stands for Hash-based Message Authentication Code. It’s a cryptographic technique that:




  • takes a message (in this case, the Base64-encoded token payload).

  • combines it with a secret key (uses your secret_key_base).

  • produces a fixed-length hash output.









🔓 How is the token verified?:



PasswordsController has a before action which calls #set_user_by_token for both the #edit and #update actions. This private method takes the token from the params and calls User.find_by_password_reset_token with it:



#set_user_by_token, from ActiveRecord::Tokens




def set_user_by_token
@user = User.find_by_password_reset_token!(params[:token])
rescue ActiveSupport::MessageVerifier::InvalidSignature
redirect_to new_password_path, alert: "Password reset link is invalid or has expired."
end






User.find_by_password_reset_token!(...) does the work here. It:




  • verifies the token signature using the HMAC digest.

  • decodes the payload.

  • checks that the exp (expiration time) hasn’t passed.

  • confirms the token’s purpose matches :password_reset.

  • extracts the user ID and loads the matching user record.



All of this happens transparently via the ActiveRecord::Tokens module included in Rails 8’s ActiveRecord::Base.









⏱ Changing the Expiry



Tokens have a default 15minute expiry hardcoded within the ActiveRecord::Tokens module, usually a good balance between usability and security. But should you wish to override this just explicity declare has_token in the User model:




has_token :password_reset, expires_in: 30.minutes












🔑 In detail - How exactly does user.password_reset_token work?:



It's not a statically defined method, so it hits Rails' ActiveRecord::TokenFor::InstanceMethods' #method_missing:




# Inside ActiveRecord::TokenFor;
# activerecord/lib/active_record/token_for.rb

def method_missing(name, *args, &block)
if name.to_s =~ /\A(.+)_token\z/
generate_token_for($1.to_sym)
else
super
end
end

def generate_token_for(purpose)
self.class.token_definitions.fetch(purpose).generate_token(self)
end







The regex matches "password_reset_token", extracts :password_reset, and passes it to #generate_token_for. Rails has an internal TokenDefinition class containing a hash of supported token types and their configuration, #generate_token_for looks up the :password_reset definition, then calls #generate_token on this configuration, which then builds a signed token (actually uses ActiveSupport::MessageVerifier.generate for the cryptogrtaphy), encoding a payload (user ID, expiry, purpose) along with an HMAC digest.



The first time this is called, Rails dynamically defines a method for password_reset_token so that future calls don’t hit method_missing.









🔑 In detail - How exactly does User.find_by_password_reset_token(token) work?:



Again not a predefined method, #find_by_password_reset_token(token) also relies on Rails’ ActiveRecord::TokenFor, specifically the class level #method_missing from TokenFor::ClassMethods:




# Inside ActiveRecord::TokenFor;
# activerecord/lib/active_record/token_for.rb

def method_missing(name, *args, &block)
if name.to_s =~ /\Afind_by_(.+)_token\z/
find_by_token($1.to_sym, *args)
else
super
end
end

def find_by_token(purpose, encoded_token)
token_def = token_definitions.fetch(purpose)
id = token_def.fetch_id(encoded_token)
return nil unless id

find_by(id: id)
end






When User.find_by_password_reset_token(token) is called, the regex in #method_missing matches the method name, extracting :password_reset, which it passes to #find_by_token along with the encoded token. Then, just like in #generate_token_for, the token configuration is looked up from Rails’ TokenDefinitions, and #fetch_id(encoded_token) is called on the :password_reset definition. This method verifies and decodes the token, again via ActiveSupport::MessageVerifier, and if valid, returns the user_id that was embedded in the token.



As with the instance level #method_missing, Rails caches the dynamically generated class method after the first call to avoid repeated #method_missing hits.












Conclusion



If you rolled your own, password reset functionality can be easy to get wrong and make insecure, Rails 8's authentication code provides production ready auth with password reset straight out of the box. The source code is pretty easily readable to should you wish. But hopefully this post provides you with a good enough summary understanding of how it works so to implement your own robust Rails 8 auth functionality.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Rails 8 authentication - password reset mechanics

Thematisch verwandte Begriffe: Rails, authentication, password, reset · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-79918 | MaxKB is an open-source AI assistant for enterprise. Prior to version 2.…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick