Ruby on Rails: How to Use Oauth2::Accesstoken.Post

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



Leave a reply



Submit