14

I have a rails app that I am attempting to sync with an android app. I've successfully set up authentication using Doorkeeper as the server and Oltu as the client.

My app tracks habits which exist as per-user lists. My index method in the habits controller is:

def index
  @habits = current_user.habits
end

When authenticating via Devise this method works, when using Doorkeeper current_user is nil.

dysbulic
  • 3,005
  • 2
  • 28
  • 48

4 Answers4

10

From Doorkeeper's README ...

Authenticated resource owner

If you want to return data based on the current resource owner, in other words, the access token owner, you may want to define a method in your controller that returns the resource owner instance:

class Api::V1::CredentialsController < Api::V1::ApiController
  before_action :doorkeeper_authorize!
  respond_to    :json

  # GET /me.json
  def me
    respond_with current_resource_owner
  end

  private

  # Find the user that owns the access token
  def current_resource_owner
    User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
  end
end

In this example, we're returning the credentials (me.json) of the access token owner.

King'ori Maina
  • 4,440
  • 3
  • 26
  • 38
9

I would override current_user in your base API controller, something like:

private

def current_user
  @current_user ||= User.find(doorkeeper_token[:resource_owner_id])
end
Chris
  • 6,076
  • 11
  • 48
  • 62
9

I have an API that needed to allow authentication via Doorkeeper OR Devise. The following solution allows the main application to use the same endpoints that Oauth clients would use and share the current_user method.

before_action :doorkeeper_authorize!, unless: :user_signed_in?

def current_user
  @current_user ||= if doorkeeper_token
                      User.find(doorkeeper_token.resource_owner_id)
                    else
                      warden.authenticate(scope: :user)
                    end
end
KPheasey
  • 1,765
  • 16
  • 22
  • 2
    You are a genius! I was looking for such a beautiful solution (as I wanted to do the exact same thing as you did: use my API with Doorkeeper OR Devise)! Thanks a lot for sharing it! – Kulgar Jun 29 '18 at 18:09
  • This should be marked as the right answer – Yuri Sidorov Dec 21 '22 at 21:10
0

I don't know if this is the right method or not, but a solution is to do:

def index
  user = current_user
  user ||= User.find(doorkeeper_token[:resource_owner_id]) if doorkeeper_token
  @habits = user.habits
end

You can't assign to current_user or it will set it to nil.

dysbulic
  • 3,005
  • 2
  • 28
  • 48