Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple users, returning(and creating) wrong model's auth token #399

Closed
danielchoi opened this issue Oct 5, 2015 · 6 comments
Closed

Comments

@danielchoi
Copy link

Client side is using ng-token-auth.
I have "User" and "Employee" model.
Login to Employee model returns correct auth_token(valid).
Any calls that I make after that against methods using "before_action :authenticate_employee!"
creates new auth token for "User" and returns it in response header, thus updating my client(supposed to be employee with User model's auth token info)

I have narrowed down the issue to "set_user_by_token" which creates new auth token, and "update_auth_header" which response with wrong credential in the header.

 def set_user_by_token
    rc = resource_class(mapping)
    devise_warden_user =  warden.user(rc.to_s.underscore.to_sym)

both rc and devise_warden_user returns "User" when it print them out.

Here is my route... incase I am doing something wrong. My API is calling agains "a1/shops#index"

Rails.application.routes.draw do
  mount_devise_token_auth_for 'User', at: 'user_auth', controllers: {
    sessions:  'overrides/sessions'
  }
  mount_devise_token_auth_for 'Employee', at: 'employee_auth', controllers: {
    sessions:  'overrides/employee_sessions'
  }
  devise_scope :user do
  ......
  end

  devise_scope :employee do
    namespace :m1 do    
    end
    namespace :a1 do
      resources :shops, only: [:show, :index, :update]
    end
end

I will be keep digging but any help would be nice.
Thanks.

@danielchoi danielchoi reopened this Oct 8, 2015
@danielchoi
Copy link
Author

After further looking into the issue.

module A1
  class ShopsController < ApplicationController
    before_action :authenticate_employee!, only: [:index, :show, :update]

    def index
      puts current_user.to_json
      puts current_employee.to_json
     @shops = current_employee.shops.select(:id, :name)
      render json: @shops, root: 'data', each_serializer: A1::ShopListSerializer
    end

current_user shouldn't exist but... it is printing out id of current_employee.
so if current_employee.id is 3, current_user is User.find(3)

When running the Index method, set_user_by_token gets called twice.

 def set_user_by_token
    rc = resource_class(mapping)

First rc returns "Employee" and Second rc returns "User"

  render json: {}, root: 'data', each_serializer: A1::ShopListSerializer

returning {} json only triggers set_user_by_token once.
and does return correct auth credential to the header.

@danielchoi
Copy link
Author

more.. detail
using binding.pry....

From: /Users/daniel/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/instrumentation.rb @ line 43 ActionController::Instrumentation#render:

    41: def render(*args)
    42:   render_output = nil
 => 43:   self.view_runtime = cleanup_view_runtime do
    44:     Benchmark.ms { render_output = super }
    45:   end
    46:   render_output
    47: end

[1] pry(#<A1::ShopsController>)> next
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
   (0.5ms)  BEGIN
  SQL (0.9ms)  UPDATE "users" SET "tokens" = $1, "updated_at" = $2 WHERE "users"."id" = $3

If I go more in depth

From: /Users/daniel/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/abstract_controller/rendering.rb @ line 25 AbstractController::Rendering#render:

    23: def render(*args, &block)
    24:   options = _normalize_render(*args, &block)
 => 25:   self.response_body = render_to_body(options)
    26:   _process_format(rendered_format, options) if rendered_format
    27:   self.response_body
    28: end

[1] pry(#<A1::ShopsController>)> next
  User Load (1.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
   (0.5ms)  BEGIN
  SQL (1.0ms)  UPDATE "users" SET "tokens" = $1,

that is where users's token is being updated...

@danielchoi
Copy link
Author

I have created new app from scratch, and it seems to work fine....
Time to get dirty and eliminate the issue one gem at a time.
I will close this for now.

@pedroviana
Copy link

@danielchoi I am facing a similar issue, not with two different models but sometimes the tokens on response its from another user than I set on the request. Did you find something to help?

@noopurj
Copy link

noopurj commented Jan 25, 2017

I have two models called 'User' and 'Worker' and I am using devise_token_auth only for 'Worker' but rc in set_user_by_token returns 'User' which is why I am getting a no method error for find_by_uid because 'User' class does not have that method, how do I get token_validation to use 'Worker' model?
sign_in uses the correct Model 'Worker', it's only token_validation that tries to use the wrong Model.

@danielchoi @pedroviana
Did you manage to solve it?

@danielchoi
Copy link
Author

@noopurj
I actually gave up on fixing the existing issue.
I ended up using Employee Model with Devise and creating my own token_auth for User using authenticate_or_request_with_http_token. Sorry can't be of any help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants