I have a Rails app with OAuth API. I'm using Doorkeeper gem for the OAuth 2 authentication. My API allows posting messages with image file attachments. I'd like to test it from Ruby console. Now, the problem is - how do I sign the post requests with the access token?
Doorkeeper wiki provides a tutorial on testing API with the OAuth2 gem itself. The problem there is that OAuth2 class doesn't provide ways of posting multiparted messages with the file attachments (as far as I got it).
https://github.com/applicake/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem
Then again there is multipart-post gem, which allows posting files as attachment to the Rails API. But I don't get how to sign such request with an access_token, and to pass the Doorkeeper authentication.
https://github.com/nicksieger/multipart-post
So what is the proper way of posting multiparted messages to Rails API signed with the access_token?
The oauth2 gem seems to not support multipart upload. Check this issue: https://github.com/intridea/oauth2/issues/81
An workaround would include the access_token in your parameters, either as a query string or as a header. Following the example in README:
require 'net/http/post/multipart'
url = URI.parse('http://www.example.com/upload')
File.open("./image.jpg") do |jpg|
req = Net::HTTP::Post::Multipart.new url.path,
"file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
# here you include the token in headers
req['Authorization'] = "Bearer #{THE_ACCESS_TOKEN}"
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
end
You also have to explicitly set the ssl on if you have this error:
EOFError in YourController#youraction
end of file reached
Exemple
require 'net/http/post/multipart'
url = URI.parse('http://www.example.com/upload')
File.open("./image.jpg") do |jpg|
req = Net::HTTP::Post::Multipart.new url.path,
"file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
# here you include the token in headers
req['Authorization'] = "Bearer #{THE_ACCESS_TOKEN}"
http = Net::HTTP.new(url.host, url.port)
#mention the use of ssl
http.use_ssl = true
res = http.request(req)
end
Related
Got my tokens and can call the core API, but when I call
https://api.dropbox.com/1/account/info
I get a
{"error": "Invalid OAuth request."}
According to the documentation (https://www.dropbox.com/developers/core/docs#account-info) there are no parameters except the locale, only the GET, which is suspicious.
The use-case I am exercising validates if the access token wasn't revoked by checking the current user's account info.
I am accessing the core-api via HTTP and not via the libraries provided (Python, Ruby, PHP, ...)
You have to add your access token in your url connection by setting the authorization header with your token.
System.out.println("accesstoken:" + access_token);
String token="Bearer ";
token+=access_token;
if (access_token != null) {
URL url = new URL(
"https://api.dropbox.com/1/account/info?locale=English");
connection = (HttpURLConnection) url.openConnection();
This works for me.
I am building a web app requiring access to a users gmail using Oauth2. I registered my app and can get the initial code, but can't figure out how to get an access token and refresh code afterwards.
First, the user is sent to a secure google page to put in user name/password. Afterwards, google redirects the user to something like:
127.0.0.1/oauth2callback?code=4/ux5gNj-_mIu4DOD_gNZdjX9E
I have this method below to handle the redirect. The code is sent with other info in a post request back to Google in exchange for a access token and refresh code. Unfortunately the response in the bottom has blank body. What am I doing wrong? Do I need to call another function on response to get the access token?
def oauth2callback
require "uri"
require "net/http"
uri = URI.parse("https://accounts.google.com/o/oauth2/token")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(
{'code'=>params[:code],
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => '127.0.0.1:3000/oauth2callback',
'grant_type' => 'authorization_code'})
http.use_ssl = true
response = http.request(request)
#response.body() is blank
end
Your redirect uri must match exactly the one, the user got redirected to. In your case this is 127.0.0.1/oauth2callback without :3000.
However, I believe that for Google both uri's needn't to be identical, but at least defined in the developer console, so maybe you could try adding 127.0.0.1:3000/oauth2callback to your developer console.
Im using oauth gem in my rails application.
gem 'omniauth-facebook', '1.4.0'
gem "omniauth-google-oauth2"
Facebook client-side authentication is working properly. I followed,
http://railscasts.com/episodes/360-facebook-authentication
Client-side authentication for google is not working or I couldn't get a handle of it.
I see this coffee script being responsible for facebook client side authentication,
jQuery ->
$('body').prepend('<div id="fb-root"></div>')
$.ajax
url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js"
dataType: 'script'
cache: true
window.fbAsyncInit = ->
FB.init(appId: 145280228983243, cookie: true)
$('#sign_in').click (e) ->
e.preventDefault()
FB.login (response) ->
window.location = '/auth/facebook/callback' if response.authResponse
$('#sign_out').click (e) ->
FB.getLoginStatus (response) ->
FB.logout() if response.authResponse
true
What should i do for google client-side authentication?
I just want when a user clicks on "log in with google" a pop-up window
should appear and ask for user-id and password and before asking, it
should check whether the users information is already available on the
browser(client-side) and if available, dont prompt for the user-id and
password, go ahead and login.
I have the same problem and it seems that omniauth-google-oauth2 doesn't support client-side authentication this way as the facebook gem does.
The omniauth-facebook gem, when building access_token, checks if the signed request is present and if it's valid, then it uses access_token provided by request.params or cookie. Otherwise it queries access_token from Facebook with the provided authorization_code.
The omniauth-google-oauth2 gem does only the second operation and because redirect_uri must be same on the initial and on the verification request, you cannot use the gem's current version this way.
I have found one fork https://github.com/pivotal-geostellar/omniauth-google-oauth2/tree/client_login with the example http://pivotallabs.com/facebook-and-googleplus-javascript-sdk-sign-in-with-devise-ror/ but it's not secure to read access_token from request.params without validating it on the server-side.
update
I found a way to verify access_token by id_token and made a pull request to the gem https://github.com/zquestz/omniauth-google-oauth2/pull/50
In my Rails 3 app, I am able to successfully authenticate using Oauth2 and able to get the metadata for a file. The downloadUrl is
https://doc-10-3o-docs.googleusercontent.com/docs/securesc/tj647mo7q16s2rquitcrcv800pkn7gcf/ap67p147th03cn8rjpu68i8qva3p7i8j/1345240800000/02289284805103305740/02289284805103305740/0BwsQ03A3DXbCTVBjUDlNNzNJNDQ?h=16653014193614665626&e=download&gd=true
The documentation states that I must do the following:
Gets a file's metadata by ID. To download a file's content, send an authorized HTTP GET request to the file's downloadUrl
I do not wish to use Google APIs Client Library for Ruby, but simply formulate a HTTP Request using HTTParty
Here is a snippet of the code I've been trying to get to work
response = HTTParty.get(https://doc-10-3o-docs.googleusercontent.com/docs/securesc/tj647mo7q16s2rquitcrcv800pkn7gcf/ap67p147th03cn8rjpu68i8qva3p7i8j/1345240800000/02289284805103305740/0?access_token={token})
open("/User/mymachine/test.pdf", 'wb'){|pdf| pdf << response.body}
I'm pretty sure I'm formulating the request wrong. Any help would be greatly appreciated. Thanks in advance.
You have to add the Authorization: Bearer header to your request, together with the access token you retrieved during the OAuth 2.0 flow.
Basically, your HTTP request must look like the one in the OAuth 2.0 documentation:
https://developers.google.com/accounts/docs/OAuth2WebServer#callinganapi
I'm not a Ruby expert, but the request using HTTParty should be:
response = HTTParty.get(downloadUrl, :headers => {"Authorization" => "OAuth {token}"})
Where downloadUrl is the one you got from the file's metadata and token is the access token you retrieved when performing authorization.
I am new to using APIs of Websites. But since a long time I wanted to learn this and today started with the simple example of how to access information from soundcloud. Here is the code of the simple example from their website
require 'rubygems'
gem 'soundcloud-ruby-api-wrapper'
require 'soundcloud'
gem 'oauth'
require 'oauth'
# Create a Soundcloud OAuth consumer token object
sc_consumer = Soundcloud.consumer('YOUR_APPLICATION_CONSUMER_TOKEN','YOUR_APPLICATION_CONSUMER_SECRET')
# Create an OAuth access token object
access_token = OAuth::AccessToken.new(sc_consumer, 'YOUR_OAUTH_ACCESS_TOKEN', 'YOUR_OAUTH_ACCESS_SECRET')
# Create an authenticated Soundcloud client, based on the access token
sc_client = Soundcloud.register({:access_token => access_token})
# Get the logged in user
my_user = sc_client.User.find_me
# Display his full name
p "Hello, my name is #{my_user.full_name}"
I know what to set as:
'YOUR_APPLICATION_CONSUMER_TOKEN'
'YOUR_APPLICATION_CONSUMER_SECRET'
as this was given when registering a application on soundcloud.
I set the 'YOUR_OAUTH_ACCESS_TOKEN' to http://api.soundcloud.com/oauth/access_token
which was also written on the soundcloud site, but I have no idea where to get the
_YOUR_OAUTH_ACCESS_SECRET_ from.
Is this access secret also a random string that I get from somewhere, do I have to generate it by myself.
EDIT As suggested in the answer of the Elite Gentlemen I also tried the Soundcloud example on authentication. I post here the piece of code which already leads to the error:
require 'rubygems'
gem 'soundcloud-ruby-api-wrapper'
require 'soundcloud'
# oAuth setup code:
# Enter your consumer key and consumer secret values here:
#consumer_application = {:key => 'QrhxUWqgIswl8a9ESYw', :secret => 'tqsUGUD3PscK17G2KCQ4lRzilA2K5L5q2BFjArJzmjc'}
# Enter the path to your audio file here.
path_to_audio_file = "your/absolute/path/to/audio_file.ext"
# Set up an oAuth consumer.
#consumer = OAuth::Consumer.new #consumer_application[:key], #consumer_application[:secret],
{
:site => 'http://api.sandbox-soundcloud.com',
:request_token_path => '/oauth/request_token',
:access_token_path => '/oauth/access_token',
:authorize_path => '/oauth/authorize'
}
# Obtain an oAuth request token
puts "Get request token"
request_token = #consumer.get_request_token
The error message I receive then is:
OAuth::Unauthorized: 401 Unauthorized
method token_request in consumer.rb at
line 217 method get_request_token in
consumer.rb at line 139 at top
level in test1.rb at line 25
How can this simple example fail?
The answer to the question is very simple. My problem was that I had
registered my application on the soundcloud production system
soundcloud.com but directed my requests against sandbox-soundcloud.com.
I had to go to sandbox-soundcloud.com, register a new user account and make a
new client application and everything worked perfectly.
More information on the Sandbox is available here:
http://github.com/soundcloud/api/wiki/Appendix-B-Sandbox
As with OAuth, you will have to register your application with Soundcloud if you want the end-user to access Soundcloud's protected resources through your application.
When you request an access_token from Soundcloud using OAuth, it will return you and access_token and a oauth_token_secret. That oauth_token_secret is what you mentioned as YOUR_OAUTH_ACCESS_SECRET
I don't know how familiar you are with OAuth. The documentation can be found here.
Edit OAuth authorization scheme changed a while back, (e.g. getting an access token requires you to specify a oauth_verifier).
See the SoundCloud example on Authentication using the latest OAuth specification.