lynndylanhurley / lynndylanhurley/devise_token_auth

unable to sign_out user1 and sign_in user2 in 1 call.

Open
#874 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Ruby
Stars
3.6k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

I use devise_token_auth as authentication for an API-backend. To be able to view what other people would see, i use a header that identifies a user, and should show you the call as if you were that user, if you have the authority to do so (read: you are an admin).

When i used

new_user = User.findByUid request.headers['x-fake-user']
sign_out current_api_user
sign_in new_user

i still got the old user as current_api_user. To note here is that i use both devise and devise_token_auth, both on User, but devise is only for admin login to adminpanel, devise_token_auth is used seperate and without the use_legacy_devise feature because i do not want sessions over multiple calls if used with a token.

as a workaround i extended the SetUserByToken Concern and have overwritten the set_user_by_token method to use this header and log in that user after the admin is authenticated and before he is signed_in. But now the function does not update any more to newer versions. So can this behavior of sign_out (and sign_in) be fixed to create a new session?

for those with the same problem, here is my workaround code untill it is fixed:

module SetUserByTokenAndSwitchUser
  extend ActiveSupport::Concern
  include DeviseTokenAuth::Concerns::SetUserByToken

  # user auth
  def set_user_by_token(mapping=nil)
    # determine target authentication class
    rc = resource_class(mapping)

    # no default user defined
    return unless rc

    #gets the headers names, which was set in the initialize file
    uid_name = DeviseTokenAuth.headers_names[:'uid']
    access_token_name = DeviseTokenAuth.headers_names[:'access-token']
    client_name = DeviseTokenAuth.headers_names[:'client']

    # parse header for values necessary for authentication
    uid        = request.headers[uid_name] || params[uid_name]
    @token     ||= request.headers[access_token_name] || params[access_token_name]
    @client_id ||= request.headers[client_name] || params[client_name]

    # client_id isn't required, set to 'default' if absent
    @client_id ||= 'default'

    # ensure we clear the client_id
    if !@token
      @client_id = nil
      return
    end

    return false unless @token

    # mitigate timing attacks by finding by uid instead of auth token
    user = uid && rc.find_by_uid(uid)

    if user && user.valid_token?(@token, @client_id)
      # sign_in with bypass: true will be deprecated in the next version of Devise
      if user.has_role?(:admin) && !request.headers['x-fake-user'].nil?
        @admin_user = user
        user = rc.find_by_email(request.headers['x-Switch-User'])
        bypass_sign_in(user, scope: :user)
      else
        bypass_sign_in(user, scope: :user)
      end
      return @resource = user
    else
      # zero all values previously set values
      @client_id = nil
      return @resource = nil
    end
  end

  def update_auth_header
    if @admin_user && !@admin_user.nil?
      @resource = @admin_user
    end
    super
  end

end

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the DeviseTokenAuth SetUserByToken concern and its set_user_by_token and update_auth_header entry points, then reproduce the sign_out/current_api_user/sign_in sequence described in the issue. Done means the requested user becomes current_api_user in the same call while preserving the admin context and token authentication behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rails, ruby
Domain
api, authentication, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.