Search code examples
ruby-on-railscookiesactiveadminsession-cookiesgrape-api

Authenticate active admin user in grape api endpoint


So here are the components of my application

admin panel is on myapp.com/admin built with active admin. then I have a dashboard for users at dashboard.myapp.com built with AngularJs and then I have api built with grape at myapp.com/api.

I have a feature on my admin panel where an admin can log in on the dashboard as another user. we call this capture_session. basically the users session is captured by admin and we drop a cookie admin_capture whose value is the id of the admin_user.

now here is what I want to achieve. in one of my grape api endpoints I need validate that the session is captured and that the admin user who has captured the session is also logged in on the admin panel.

now figuring out whether the session is captured or not is easy as I already have a cookie for that. but how can I verify that the admin user is logged in? as active admin methods and helpers cannot be called in grape api endpoint. can I achieve this with cookies or sessions? any help will be highly appreciated

Thanks


Solution

  • So here is how I solved this.. I set another cookie admin_session with the encrypted session and then returned the same cookie as header from the dashboard.

    In the grape endpoint I decrypted the session and got the admin user's id and initial part of the encrypted password. and used this information to verify admin.

    here is the code.

      admin_id      = ADMIN_ID_HEADER
      admin_session = ADMIN_SESSION_HEADER
      admin_user    = AdminUser.find_by_id(admin_id)
      return unless admin_id.present? && admin_session.present? && admin_user.present?
    
      salt          = Rails.application.config.action_dispatch.encrypted_cookie_salt
      signed_salt   = Rails.application.config.action_dispatch.encrypted_signed_cookie_salt
      key_generator = ActiveSupport::KeyGenerator.new(ENV['SECRET_KEY_BASE'], :iterations => 1000)
      secret        = key_generator.generate_key(salt)
      signed_secret = key_generator.generate_key(signed_salt)
      encryptor     = ActiveSupport::MessageEncryptor.new(secret, signed_secret, :serializer => ActiveSupport::MessageEncryptor::NullSerializer)
      session_data  = JSON.parse(encryptor.decrypt_and_verify(CGI::unescape(admin_session))) rescue {}