Closed dustinschaerer closed 3 years ago
Post your code?
I've tried a few methods.
The first was to use a Rails initiailizer, "config/initiailizers/quickbooks_oauth.rb":
oauth_params = { site: "https://appcenter.intuit.com/connect/oauth2", authorize_url: "https://appcenter.intuit.com/connect/oauth2", token_url: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer" } oauth2_client = OAuth2::Client.new(ENV['OAUTH_CLIENT_ID'], ENV['OAUTH_CLIENT_SECRET'], oauth_params)
quickbooks_controller.rb
def authenticate
oauth_params = {
site: "https://appcenter.intuit.com/connect/oauth2",
authorize_url: "https://appcenter.intuit.com/connect/oauth2",
token_url: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
}
oauth2_client = OAuth2::Client.new(ENV['OAUTH_CLIENT_ID'], ENV['OAUTH_CLIENT_SECRET'], oauth_params)
redirect_uri = "https://methowreservations.com/quickbooks/oauth_callback"
grant_url = oauth2_client.auth_code.authorize_url(redirect_uri: redirect_uri, response_type: "code", state: SecureRandom.hex(12), scope: "com.intuit.quickbooks.accounting")
redirect_to grant_url
end
# https://methowreservations.com/quickbooks/oauth_callback?code=AB11581719107of59Ui0ykhqs5v2w9TCIMeUt7M3cK8TpZRlbr&state=81455b781ef7a2b20c6792a2&realmId=9130347936512676
def oauth_callback
if params[:state].present?
redirect_uri = "https://methowreservations.com/quickbooks/oauth_callback"
if resp = oauth2_client.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
existing_service = ThirdPartyService.where( realm_id: params[:realmId] ).first
if existing_service.present?
existing_service.access_token = resp.token
existing_service.refresh_token = resp.refresh_token
existing_service.save
else
ThirdPartyService.new(name: 'quickbooks',
realm_id: params[:realmId],
access_token: resp.token,
refresh_token: resp.refresh_token,
access_token_expires_at: DateTime.now + 58.minutes,
refresh_token_expires_at: DateTime.now + 24.hours).save
end
flash.notice = "Your QuickBooks account has been successfully linked."
@msg = 'Redirecting. Please wait.'
@url = '/operator/process_tab'
render 'close_and_redirect', layout: false
end
end
end
oauth2_client doesn't seem to stay set between the controller actions.
I was able to make to headway (hackety-hackety) if I reinitialized the oauth2_client object inside my controller's authenticate action, but the object was gone once it hits the oauth_callback method.
Thanks!
Local variables created in a Rails initializer are not visible outside that initializer. You could make them Ruby Globals by using dollar sign variables,
$oauth2_client = ...
But using global variables is a bad practice.
If you are creating the client in a controller what about using a before_filter to create it as an instance variable thats visible to other actions?
Thank you! I'll give that a whirl. I was trying to follow the README but I obviously tripped up a bit.
I had the same confusion from the readme. Putting that code block in an initializer didn't make oauth2_client it accessible in my controllers, jobs, etc.
Is there a good way to initialize ouath2_client once and make it available across ALL of the app?
@pjrashidi @dustinschaerer exact implementation details depend on your app, but what I have done is:
Something like:
oauth2_config = YAML.load_file(File.join(Rails.root, 'config/intuit_oauth2.yml'))[Rails.env]
ENV['INTUIT_OAUTH2_CLIENT_ID'] = oauth2_config['client_id']
ENV['INTUIT_OAUTH2_CLIENT_SECRET'] = oauth2_config['client_secret']
Then in a mixin which gets mixed-into models or controllers I have
def construct_oauth2_client
options = {
site: "https://appcenter.intuit.com/connect/oauth2",
authorize_url: "https://appcenter.intuit.com/connect/oauth2",
token_url: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
}
if Rails.env.development?
options[:connection_opts] = {
proxy: "http://127.0.0.1:8888"
}
end
OAuth2::Client.new(ENV['INTUIT_OAUTH2_CLIENT_ID'], ENV['INTUIT_OAUTH2_CLIENT_SECRET'], options)
end
Then I can just call that method from anywhere and get hold of a valid client.
Documentation needs updating here. I was like...how is this documentation acting like what is defined in an initializer would be available in a controller action?
Thank you! I'll give that a whirl. I was trying to follow the README but I obviously tripped up a bit.
Nah...the docs should be updated. Maybe I'll give it a whirl. Because as they stand, what they are telling users to do won't work. And if I was 5+ years younger, I would be completely lost.
@ruckus There we go. That's more like it. Something like what you posted should be added to the readme.
Since it is almost 4PM on a Friday, and my brain is almost completely dead, I don't have the mental capacity to do that right now. But maybe I'll give a PR a go when I get a chance.
I'm trying to update our Quickbooks Integration to using Oauth2 and I keep getting an error in my quickbooks_controller that oauth2_client is undefined.
I'm also not sure what the grant_url instructions in README are referring to. Under this workflow, isn't the grant_url what's returned from the oauth2_client.auth_code.authorize_url call?
It seems like the Rails initializer is not setting that variable to be accessible in my controller.