Skip to content

Conditional authentication

Gonzalo Bulnes Guilpain edited this page Feb 9, 2016 · 2 revisions

The ability to conditionally authenticate based on given criteria is very important, allows you to have specific users to be able to use your website as an API (for example, paid users only). To enable this behavior, the trick is very simple. Let's assume your perform this in ApplicationController and let's assume you have a boolean token_authenticable column on your user model:

class ApplicationController < ActionController::Base

  acts_as_token_authentication_handler_for User,
    if: ->(controller) { controller.user_token_authenticable? }

  protected

  def user_token_authenticable?
    # This ensure the token can be used only for JSON requests (you may want to enable it for XML too, for example)
    return false unless request.format.json?
    return false if tokenized_user_identifier.blank?

    # `nil` is still a falsy value, but I want a strictly boolean field here
    tokenized_user.try(:token_authenticable?) || false
  end

  private

  def tokenized_user
    # I use email with devise, you can use whatever you want
    User.find_by(email: tokenized_user_identifier.to_s)
  end

  def tokenized_user_identifier
    # Customize this based on Simple Token Authentication settings
    request.headers['X-User-Email'] || params[:user_email]
  end

end

And that's all! Let's review the code:

  • We allow the token authentication to be valid for JSON only
  • We allow the token authentication to be valid only if a user identifier is present (a header or a param)
  • We fetch the user based on token the identifier, if no user is found, we don't perform any token authentication
  • If the user exists and it's token_authenticable? set to true, then we enable token authentication
Clone this wiki locally