Pass parameters in AccessToken post request for gem Oauth rails
You gotta use the string hash rocket for :body
and :headers
, I like Implementation-1 better though.
access_token.post('/organizations/223031/files',
"body" => {"name" => 'xyz.zip'},
"headers" => { 'Content-Type' => 'application/vnd.deere.axiom.v3+json',
'Accept'=>'application/vnd.deere.axiom.v3+json'})
Ruby on Rails - OAuth 2 multipart Post (Uploading to Facebook or Soundcloud)
Struggled with this myself. The oauth2 library is backed by Faraday for it's HTTP interaction. with a little configuration it supports uploaded files out of the box. First step is to add the appropriate Faraday middleware when building your connection. An example from my code:
OAuth2::Client.new client_id, secret, site: site do |stack|
stack.request :multipart
stack.request :url_encoded
stack.adapter Faraday.default_adapter
end
This adds the multipart encoding support to the Faraday connection. Next when making the request on your access token object you want to use a Faraday::UploadIO object. So:
upload = Faraday::UploadIO.new io, mime_type, filename
access_token.post('some/url', params: {url: 'params'}, body: {file: upload})
In the above code:
io - An IO object for the file you want to upload. Can be a File object or even a StringIO.
mime_type - The mime type of the file you are uploading. You can either try to detect this server-side or if a user uploaded the file to you, you should be able to extract the mime type from their request.
filename - What are are calling the file you are uploading. This can also be determined by your own choosing or you can just use whatever the user uploading the file calls it.
some/url - Replace this with the URL you want to post to
{url: 'params'} - Replace this with any URL params you want to provide
{file: upload} - Replace this with your multipart form data. Obviously one (or more) of the key/value pairs should have an instance of your file upload.
Using Google OAuth2 API with Ruby on Rails
That was easy but I think I was not putting the token_credential_uri
in the call to the API in my tests.
Observing this answer "How do I refresh my google_oauth2 access token using my refresh token?
" I found the right way to do it.
I just added the following params to the API call: client_id
, client_secret
, token_credential_uri
and refresh_token
.
def analytics_report
entity_conditions = { entity_type: ContractedProduct.name, entity_id: @contracted_product.id }
api_integration_refresh_token = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:refresh_token])
api_integration_profile_id = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:profile_id])
client_info = {
client_id: Rails.configuration.x.google_api['client_id'],
client_secret: Rails.configuration.x.google_api['client_secret'],
token_credential_uri: Rails.configuration.x.google_api['token_credential_uri'],
refresh_token: api_integration_refresh_token.value
}
client = Signet::OAuth2::Client.new(client_info)
service = Google::Apis::AnalyticsV3::AnalyticsService.new
service.authorization = client
profile_id = 'ga:' + api_integration_profile_id.value
start_date = Date.today.at_beginning_of_month.last_month.to_s
end_date = Date.today.at_beginning_of_month.last_month.to_s
metrics = 'ga:pageviews'
dimensions = {
dimensions: 'ga:date'
}
@report = service.get_ga_data(profile_id, start_date, end_date, metrics, dimensions)
end
cannot retrieve access token for oauth2
The way Oauth2 works is that it needs to know where to return the authentication to. This is done by defining a Redirect URI.
With browser based applications its easy to know where the authentication should be returned to. In this case it should go to a page on the website designed to handle the response form the authentication server.
With installed applications thats a little harder becouse there is no website to return to so no way of knowing an exact ip address where to send it to. In this case google creates two standard redirect uris that you can use.
urn:ietf:wg:oauth:2.0:oob and and http://localhost
Explanation of your error
In your case if you read the error message you are sending a Native redirect uri to a browser client id.
Your issue:
309181******-lnbictq23g17o7pp3e6v7vdqq9juinv9.apps.googleusercontent.com <--- Web client id
urn:ietf:wg:oauth:2.0:oob <--- Redirect uri only allowed for native clients
Solution
Go back to Google developer console and find the client id and client secret for the native (other) client you created. You cant use urn:ietf:wg:oauth:2.0:oob
with a browser client id as you have done now.
Now this really depends on what your doing here. If you are going to release this on a website someplace then leaving this as a browser client would probably be a decide id. in that case just using http://localhost for your redirect uri will solve your problem. But you should add a new redirect uri when you release this to your production website. Leaving localhost allowed in a production client is a bad idea in my opinion.
but this really depends on how you intend to use this application.
OAuth2 with intridea ruby gem
There seems to be a problem how the oauth2 gem passes variabels inside the objects so mode and param_name seems to be lost on the way. A solution to the problem would be to create a new AccessToken object with the correct parameters instead of using the shorthand. This example is tested against Foursquares api and it works.
require "oauth2"
client = OAuth2::Client.new(
"CLIENT_ID",
"CLIENT_SECRET",
:authorize_url => "/oauth2/authorize",
:token_url => "/oauth2/access_token",
:site => "https://foursquare.com/"
)
puts client.auth_code.authorize_url(:redirect_uri => "http://localhost:4000")
code = gets.chomp
token = client.auth_code.get_token(code, :redirect_uri => "http://localhost:4000")
token = OAuth2::AccessToken.new(client, token.token, {
:mode => :query,
:param_name => "oauth_token",
})
response = token.get('https://api.foursquare.com/v2/users/self/checkins')
puts response.body
Related Topics
Creating a Test Suite Using Ruby Minitest
Using Activemodel::Serializer in Rails - JSON Data Differs Between JSON and Index Response
Getting Ruby Function Object Itself
Ror - How to Remove Rails 4.1.1 Version
How to Call a Parent App's Helper Method from a Rails 3.1 Engine
How to Run "Bundle Exec Jekyll New ."
How to Best Handle Per-Model Database Connections with Activerecord
Loading Class Descendants in Rails Development
What Is the Most Ruby-Ish Way of Accessing Nested Hash Values at Arbitrary Depths
Converting an Array of Hashes to One Hash in Ruby
Uploading a File to a Website with Ruby/Rails
How to Connect to Browser Using Ruby Selenium Webdriver
Need to Use Add_Index on Migration for Belongs_To/Has_Many Relationship? (Rails 3.2, Active Record)
Grouped Collection Select Alphabetical Order Rails
Best Way to Handle Category/Subcategory Relationship Ruby on Rails
In Ruby How to Automatically Populate Instance Variables Somehow in the Initialize Method