Ankit Samarthya
Ankit Samarthya

Reputation: 614

How can I get current_user by directly visiting an API url in rails app? I am using ng-auth-token and devise_token_auth for authentication

I am using ng-auth-token and devise_token_auth for authentication which is working fine. I am able to login from front end but when i visit an API url directly in browser it doesnt show any current_user. What i want to do is i want to integrate paypal checkout, so when i come back from paypal to my app after user authorization, current_user is nil and also session variable is empty (even if i set some session variable before going to paypal site).

If i add

before_action :authenticate_user!

it gives me

Filter chain halted as :authenticate_user! rendered or redirected

even if i am logged in.

I don't know how can i handle these callback response from other apps.

Upvotes: 1

Views: 557

Answers (3)

Dawid Grzesiak
Dawid Grzesiak

Reputation: 402

I have ended up with this code in ApplicationController:

before_action :merge_auth_headers

def merge_auth_headers
  if auth_headers = cookies[:auth_headers]
    request.headers.merge!(JSON.parse(auth_headers))
  end
end

Upvotes: 0

Mike V
Mike V

Reputation: 136

Addon to Ankit's solution (rep too low to comment):

This was failing for me on post requests because Rails was stripping out the cookies due to protect_from_forgery being set:

class ApplicationController < ActionController::Base
  include DeviseTokenAuth::Concerns::SetUserByToken
  include Pundit
  protect_from_forgery with: :null_session # <-- this was the culprit
end

Removing protect_from_forgery entirely "solved" the issue, though I'm not happy with it.

The real issue (on my end, at least) is that ng-token-auth is supposed to be including the token in the header, but is only found in the cookies. My current guess is that either 1) ng-token-auth isn't properly setting its HttpInterceptor, or 2) some other interceptor is messing with it after the fact. (I've seen the ng-file-upload can cause issues, but I'm not using that...)

Upvotes: 1

Ankit Samarthya
Ankit Samarthya

Reputation: 614

I found a workaround to this, but still waiting for a proper solution.

# In ApplicationController
def authenticate_current_user
 head :unauthorized if get_current_user.nil?
end

def get_current_user
 return nil unless cookies[:auth_headers]
 auth_headers = JSON.parse cookies[:auth_headers]

 expiration_datetime = DateTime.strptime(auth_headers["expiry"], "%s")
 current_user = User.find_by(uid: auth_headers["uid"])

 if current_user &&
   current_user.tokens.has_key?(auth_headers["client"]) &&
   expiration_datetime > DateTime.now

   @current_user = current_user
 end
 @current_user
end

and use this in controllers

# In any controllers
before_action :authenticate_current_user

source: https://github.com/lynndylanhurley/devise_token_auth/issues/74

Thanks.

Upvotes: 1

Related Questions