The responsible code is not environment specific yet it works locally but not in production:
POST request to my app's /oauth/token should redirect to a controller overriding default Doorkeeper Token response as shown in the first route
require 'api_constraints'
Rails.application.routes.draw do
use_doorkeeper do
controllers :tokens => 'access_token'
end
# Other routes
end
The above works fine on a local server however in production[Heroku] this seems to be ignored and is instead routed to default doorkeeper class for no apparent reason. Therefore the response with the token does not contain the user id.
REQUEST TO "https://myapp.herokuapp.com/oauth/token"
POST /oauth/token HTTP/1.1
Host: myapp.herokuapp.com
Cache-Control: no-cache
Postman-Token: xxxxxxxx
Content-Type: application/x-www-form-urlencoded
grant_type=password&email=john%40gmail.com&password=password
THIS RETURNS JSON RESPONSE:
{
"access_token": "XXXXXX",
"token_type": "bearer",
"created_at": 1466340696
}
The same request to "http://localhost:3000/oauth/token" returns
{
"access_token": "XXXXXX",
"token_type": "bearer",
"created_at": 1466341435,
"id": 1
}
with the correctly included user_id. I'm not sure if there is some kind of a cache issue which makes my production server use the old routes file. I've tried restarting dynos and push further changes to to heroku master however this did not resolve the issue.
class AccessTokenController < Doorkeeper::TokensController
# Overriding create action
# POST /oauth/token
def create
response = strategy.authorize
body = response.body
if response.status == :ok
# User the resource_owner_id from token to identify the user
user = User.where(response.token.resource_owner_id).first rescue nil
unless user.nil?
### If you want to render user with template
### create an ActionController to render out the user
# ac = ActionController::Base.new()
# user_json = ac.render_to_string( template: 'api/users/me', locals: { user: user})
# body[:user] = Oj.load(user_json)
### Or if you want to just append user using 'as_json'
body[:id] = response.token.resource_owner_id
end
end
self.headers.merge! response.headers
self.response_body = body.to_json
self.status = response.status
rescue Doorkeeper::Errors::DoorkeeperError => e
handle_token_exception e
end
end
Apologies for any confusion and thank you in advance for any assistance with this.
Got it to work at last.
For reasons unknown to me Postgres was not finding the user causing it to be nil and the subsequent if statement unless user.nil?
was not executed, hence why the resource_owner_id was not attaching. However locally with SQLite3 this was not an issue. I'm sure there is something very basic I'm missing here with development on Heroku or PG in general. I would appreciate any advise, if I find anything myself I'll post it here also.
Working version of the access token controller
class AccessTokenController < Doorkeeper::TokensController
# Overriding create action
# POST /oauth/token
def create
response = strategy.authorize
body = response.body
if response.status == :ok
# Return user id
body[:id] = response.token.resource_owner_id unless nil
end
self.headers.merge! response.headers
self.response_body = body.to_json
self.status = response.status
rescue Doorkeeper::Errors::DoorkeeperError => e
handle_token_exception e
end
end