Hi.
I'm trying to setup doorkeeper to work with rails-api only application and getting when trying to authenticate
NameError: uninitialized constant AccessToken
doorkeeper-4.3.1/lib/doorkeeper/oauth/token.rb:15:in `authenticate'
```
doorkeeper (4.3.1)
rails (5.1.5)
I want to use doorkeeper in this application only for the purpose of request authentication and it is connected to the same database which is the other application (which is OAuth provider) is using.
So basically there are 2 rails applications: one is regular rails app (OAuth provider) and the other one is just API consuming same database.
```ruby
module Api
module V1
class ApiController < ActionController::API #:nodoc:
before_action :doorkeeper_authorize!
def current_resource_owner
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
end
end
end
end
Maybe there is some additional setup needed in order to make it work with rails-api or some middlewares are missing. Thanks for the help in advance!
We have some support for Rails 5 API mode in master (it is not released yet). Maybe you can check it (just enable api_only option in configuration)? Also, can you please provide your Doorkeeper initializer and full error backtrace?
Thanks for jumping in, @nbulaj.
No luck with master branch as well.
Since I'm not using this app as OAuth provider, doorkeeper configuration is pretty slim:
Doorkeeper.configure do
orm :active_record
api_only
end
Setting base_controller 'ActionController::API' also didn't helped.
Started GET "/api/v1/contacts" for 127.0.0.1 at 2018-03-23 18:38:56 +0100
Processing by Api::V1::ContactsController#index as JSON
Completed 500 Internal Server Error in 438ms
NameError (uninitialized constant AccessToken):
/home/denis/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/bundler/gems/doorkeeper-e8474c48bc35/lib/doorkeeper/oauth/token.rb:15:in `authenticate'
/home/denis/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/bundler/gems/doorkeeper-e8474c48bc35/lib/doorkeeper/rails/helpers.rb:71:in `doorkeeper_token'
/home/denis/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/bundler/gems/doorkeeper-e8474c48bc35/lib/doorkeeper/rails/helpers.rb:17:in `valid_doorkeeper_token?'
/home/denis/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/bundler/gems/doorkeeper-e8474c48bc35/lib/doorkeeper/rails/helpers.rb:7:in `doorkeeper_authorize!'
activesupport (5.1.5) lib/active_support/callbacks.rb:413:in `block in make_lambda'
activesupport (5.1.5) lib/active_support/callbacks.rb:197:in `block (2 levels) in halting'
actionpack (5.1.5) lib/abstract_controller/callbacks.rb:12:in `block (2 levels) in <module:Callbacks>'
activesupport (5.1.5) lib/active_support/callbacks.rb:198:in `block in halting'
activesupport (5.1.5) lib/active_support/callbacks.rb:507:in `block in invoke_before'
activesupport (5.1.5) lib/active_support/callbacks.rb:507:in `each'
activesupport (5.1.5) lib/active_support/callbacks.rb:507:in `invoke_before'
activesupport (5.1.5) lib/active_support/callbacks.rb:130:in `run_callbacks'
actionpack (5.1.5) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (5.1.5) lib/action_controller/metal/rescue.rb:20:in `process_action'
actionpack (5.1.5) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (5.1.5) lib/active_support/notifications.rb:166:in `block in instrument'
activesupport (5.1.5) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.1.5) lib/active_support/notifications.rb:166:in `instrument'
actionpack (5.1.5) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (5.1.5) lib/action_controller/metal/params_wrapper.rb:252:in `process_action'
activerecord (5.1.5) lib/active_record/railties/controller_runtime.rb:22:in `process_action'
actionpack (5.1.5) lib/abstract_controller/base.rb:124:in `process'
actionview (5.1.5) lib/action_view/rendering.rb:30:in `process'
actionpack (5.1.5) lib/action_controller/metal.rb:189:in `dispatch'
actionpack (5.1.5) lib/action_controller/metal.rb:253:in `dispatch'
actionpack (5.1.5) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (5.1.5) lib/action_dispatch/routing/route_set.rb:31:in `serve'
actionpack (5.1.5) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (5.1.5) lib/action_dispatch/journey/router.rb:33:in `each'
actionpack (5.1.5) lib/action_dispatch/journey/router.rb:33:in `serve'
actionpack (5.1.5) lib/action_dispatch/routing/route_set.rb:844:in `call'
rack (2.0.4) lib/rack/etag.rb:25:in `call'
rack (2.0.4) lib/rack/conditional_get.rb:25:in `call'
rack (2.0.4) lib/rack/head.rb:12:in `call'
activerecord (5.1.5) lib/active_record/migration.rb:556:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
activesupport (5.1.5) lib/active_support/callbacks.rb:97:in `run_callbacks'
actionpack (5.1.5) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.1.5) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.1.5) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.1.5) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.1.5) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.1.5) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.1.5) lib/rails/rack/logger.rb:24:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/request_id.rb:25:in `call'
rack (2.0.4) lib/rack/runtime.rb:22:in `call'
activesupport (5.1.5) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.5) lib/action_dispatch/middleware/static.rb:125:in `call'
rack (2.0.4) lib/rack/sendfile.rb:111:in `call'
railties (5.1.5) lib/rails/engine.rb:522:in `call'
puma (3.11.3) lib/puma/configuration.rb:225:in `call'
puma (3.11.3) lib/puma/server.rb:624:in `handle_request'
puma (3.11.3) lib/puma/server.rb:438:in `process_client'
puma (3.11.3) lib/puma/server.rb:302:in `block in run'
puma (3.11.3) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
Try to touch ActiveRecord::Base in the end of Doorkeeper initilizer like this: puts ActiveRecord::Base.inspect
I'm wondering if it is connected with lazy models loading..
You da man! Worked like charm. Is it ok to just leave the line above in doorkeeper initializer or it is better to touch ActiveRecord::Base somewhere else?
Hmm, it is really strange why AR wasn't loaded at the moment :/ Can you show you gemfile? (not .lock) Maybe you made some AR customizations?
No, touched nothing. It's fresh rails app.
Gemfile
# frozen_string_literal: true
source 'https://rubygems.org'
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
"https://github.com/#{repo_name}.git"
end
ruby File.read('.ruby-version').match(/\d\.\d.\d/)[0]
gem 'doorkeeper', git: 'https://github.com/doorkeeper-gem/doorkeeper.git', branch: 'master'
gem 'dotenv-rails'
gem 'iso_country_codes'
gem 'pg', '~> 0.18.4'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.1.5'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.7'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem 'rack-cors'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: %i[mri mingw x64_mingw]
gem 'factory_bot_rails', '~> 4.0'
gem 'pry'
gem 'rspec-rails'
end
group :development do
gem 'listen', '>= 3.0.5', '< 3.2'
gem 'overcommit', require: false
gem 'rubocop', require: false
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :test do
gem 'dox', require: false
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
It is silly, but can you try to set 'rails' as the first gem in the list? Before doorkeeper. And try without touching AR. Bundler loads gems as they defined, so maybe it is the problem..
Nope, that didn't help :/
Any plans on when the next release (with api_only included) will be? :heart: for this gem! :tada:
@milgner I think in early April we will release an RC version so you can try it
@mojobiri could you please provide some instruction on how to setup the app to get error problem? (maybe there are something special that I must know)
ok, I will.
Btw, it is only happening on the first request and only if Content-type is not set.
Means this fails the first time and works after.
curl \
--header "Authorization: Bearer token" \
--request GET \
http://localhost:3000/contacts
And this works from the beginning:
curl \
--header "Content-type: application/json" \
--header "Authorization: Bearer token" \
--request GET \
http://localhost:3000/contacts
Sample app to reproduce the issue
Rails 5.1.5
rails new doorkeeper-test --api
cd doorkeeper-test
echo -e "\ngem 'doorkeeper', git: 'https://github.com/doorkeeper-gem/doorkeeper.git', branch: 'master'" >> Gemfile
echo "gem 'dotenv-rails'" >> Gemfile
echo "gem 'pg', '~> 0.18.4'" >> Gemfile
bundle install
echo "Doorkeeper.configure do
orm :active_record
api_only
end" > config/initializers/doorkeeper.rb
echo "class ContactsController < ApiController
def index
render json: {}
end
end" > app/controllers/contacts_controller.rb
echo "class ApiController < ActionController::API
before_action :doorkeeper_authorize!
end" > app/controllers/api_controller.rb
echo "Rails.application.routes.draw do
resources :contacts
end" > config/routes.rb
echo "2.5.0" >> .ruby-version
echo "DATABASE_URL=postgresql://postgres:postgres@localhost/DB_NAME" > .env.local
rails s
curl \
--header "Authorization: Bearer token" \
--request GET \
http://localhost:3000/contacts
I've made the sample app and done some extra steps (rails db:create , rails g doorkeeper:migration , rails db:migrate). And I've got:
Completed 401 Unauthorized in 25ms (ActiveRecord: 3.4ms)
And no problem:
Processing by ContactsController#index as /
Doorkeeper::AccessToken Load (0.5ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = $1 LIMIT $2 [["token", "token"], ["LIMIT", 1]]
:thinking:
yeah, it is ok. I just have not standard setup because I'm connecting to an existing DB and the other app is OAuth provider. So I already have doorkeeper tables in the database and don't want to run any migrations in the second app.
Hm.. I don't know how to reproduce it... Maybe you can upload your project somewhere (without all the models / controllers / etc except Doorkeeper) ?
You should get an error with the setup I wrote above if you follow it without any additional setup you did (like rails g doorkeeper:migration and rails db:migrate)
You should get an error with the setup I wrote above if you follow it without any additional setup you did (like rails g doorkeeper:migration and rails db:migrate)
But it have no sense because I would not have valid DB tables. Ok, I will try tomorrow once again
the error occurs before it reaches DB-related errors )
the error occurs before it reaches DB-related errors )
Yep, I understand it, but in my case there are was database error, not NameError exception.
@mojobiri as I mentioned above:
Use Ctrl-C to stop
Started GET "/contacts" for 127.0.0.1 at 2018-04-02 11:41:52 +0300
Processing by ContactsController#index as /
Doorkeeper::AccessToken Load (2.7ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = $1 LIMIT $2 [["token", "token"], ["LIMIT", 1]]
↳ /home/bulaj/.rvm/gems/ruby-2.4.1/bundler/gems/doorkeeper-ed95d941e584/lib/doorkeeper/models/access_token_mixin.rb:23
Doorkeeper::AccessToken Load (0.5ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = $1 LIMIT $2 [["token", "token"], ["LIMIT", 1]]
↳ /home/bulaj/.rvm/gems/ruby-2.4.1/bundler/gems/doorkeeper-ed95d941e584/lib/doorkeeper/models/access_token_mixin.rb:23
Doorkeeper::AccessToken Load (0.6ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = $1 LIMIT $2 [["token", "token"], ["LIMIT", 1]]
↳ /home/bulaj/.rvm/gems/ruby-2.4.1/bundler/gems/doorkeeper-ed95d941e584/lib/doorkeeper/models/access_token_mixin.rb:23
Doorkeeper::AccessToken Load (0.6ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."token" = $1 LIMIT $2 [["token", "token"], ["LIMIT", 1]]
↳ /home/bulaj/.rvm/gems/ruby-2.4.1/bundler/gems/doorkeeper-ed95d941e584/lib/doorkeeper/models/access_token_mixin.rb:23
Filter chain halted as :doorkeeper_authorize! rendered or redirected
Completed 401 Unauthorized in 165ms (ActiveRecord: 60.3ms)
So I just have 401 Unauthorized
I dropped database and got:
Started GET "/contacts" for 127.0.0.1 at 2018-04-02 11:45:16 +0300
ActiveRecord::NoDatabaseError (FATAL: database "DB_NAME" does not exist
):
activerecord (5.2.0.rc2) lib/active_record/connection_adapters/postgresql_adapter.rb:688:in
rescue in connect' activerecord (5.2.0.rc2) lib/active_record/connection_adapters/postgresql_adapter.rb:684:inconnect'
activerecord (5.2.0.rc2) lib/active_record/connection_adapters/postgresql_adapter.rb:215:ininitialize' activerecord (5.2.0.rc2) lib/active_record/connection_adapters/postgresql_adapter.rb:40:innew'
Any news here?
I have a non-standard setup and no one have issues with it. The workaround works for me. Let's close it.
Most helpful comment
Try to touch ActiveRecord::Base in the end of Doorkeeper initilizer like this:
puts ActiveRecord::Base.inspectI'm wondering if it is connected with lazy models loading..