Search code examples
ruby-on-railsjwtsidekiqrails-api

JWT Auth with Rails Sidekiq admin panel


I'm trying to use my existing auth system to protect the /sidekiq route. I'm using JWT with Rails-api. I'm able to read the JWT token to check if the user has an admin role but it only works on the initial request. Subsequent requests in the Sidekiq panel retrieve CSS and JS but they fail because the token is not passed along to them.

I have the following route in my routes.rb:

mount Sidekiq::Web => '/sidekiq', constraints: AdminConstraint.new

Then lib/admin_constraint.rb:

class AdminConstraint
  def matches?(request)
    token = request.params['token']
    unless token
      puts 'AdminConstraint: No token in params found'
      return false;
    end

    user = Knock::AuthToken.new(token: token).entity_for(User)
    unless user
      puts "AdminConstraint: No user found for token #{token}"
    end

    if user.admin?
      puts "AdminConstraint: User with user_id #{user.id} is an admin, access granted"
      true
    else
      puts "AdminConstraint: User with user_id #{user.id} is NOT an admin, rejecting"
      false
    end
  end
end

I'm accessing the route in my browser like so: https://example.com/sidekiq?token=<token>

Is there some way I can persist the token for subsequent requests? I can't seem to use Rails session in this lib file.


Solution

  • Is there some way I can persist the token for subsequent requests?

    This can't/shouldn't be done within a constraint in your routes.

    You'll need to provide another endpoint, which sets something in the session to show that the session has been authenticated, which you'd then check within your routing constraint.

    This could be done in a controller, or a rack middleware perhaps.