abevoelker/devise-passwordless

Suggestion: single use tokenizer example

Closed this issue · 2 comments

With Rails 7.1 and generates_token_for I was able to create a single use tokenizer example pretty easily.

Sharing in case it's helpful:

class SingleUseTokenizer
  def self.decode(token, resource_class, *args)
    resource = resource_class.find_by_token_for(:passwordless_login, token)
    raise Devise::Passwordless::ExpiredTokenError unless resource
    raise Devise::Passwordless::InvalidTokenError unless resource.is_a?(resource_class)
    [resource, {}]
  end

  def self.encode(resource, *args)
    resource.generate_token_for(:passwordless_login)
  end
end

then in my User model

  generates_token_for :passwordless_login, expires_in: passwordless_login_within do
    current_sign_in_at
  end

It relies on the current_sign_in_at attribute changing on my user after a successful login. Once it changes, the same token will always be invalid and cannot be reused.

Ooh I love this! 🚀 🎉 Want to add it as an example to the README?

PR submitted. Feel free to adjust and/or delete however you'd like!