The command line version of 'httparty' with basic authentication works simple and great:
httparty -u username:password http://example.com/api/url
But now I'm looking for the way I can add the basic auth to a HTTParty.get call from within a Rails app. First of all, for testing purposes, I want to hard code the login credentials in the Controller. Just to make sure it works. But I can't find any documentation or examples how you can pass these along.
A HTTParty.get without credentials works fine:
#blah = HTTParty.get("http://twitter.com/statuses/public_timeline.json")
But I don't see how I can make a variation on this that accepts the -u username:password part.
The next challenge for me (am very new to Ruby/Rails) is to get the user credentials from a user form and pass it along dynamically, but most important for me now it to get the hard coded version to work.
auth = {:username => "test", :password => "test"}
#blah = HTTParty.get("http://twitter.com/statuses/public_timeline.json",
:basic_auth => auth)
Two points,
If you are hitting Twitter's api, unless I'm mistaken I don't think they allow basic auth anymore :( So you may want to look into something like OmniAuth for OAuth sign-in. You don't need HTTParty or a sign-in form for this, you link to the Twitter sign-in and the user enters credentials there, then Twitter sends a callback request to your app once authenticated. OmniAuth does most of the work for you, you just pull the info you need out of what it gives you in the callback route.
But even so, you will still need the OAuth 'consumer key' and 'consumer secret' which are specific to your application (how Twitter authorizes your application, as distinguished from the user). And you don't want these, nor any auth keys, in your source code.
A typical way of doing this is stick them into a config/omniauth.yml file which is not checked in to source control:
twitter:
key: CONSUMER_KEY
secret: CONSUMER_SECRET
And then load them in an initializer config/initializers/omniauth.rb :
consumers = YAML.load("#{Rails.root}/config/omniauth.yml")
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, consumers['twitter']['key'], consumers['twitter']['secret']
end
You could take a similar approach with loading basic auth username/passwords, just stick them in some object that you'll have access to from wherever you make the HTTParty calls.
Related
I'm trying to create a script to access the Quizlet API
Those API are protected with OAuth2 and I'm using this oauth2 ruby gem https://github.com/intridea/oauth2
The gem's GitHub page shows an example but for me doesn't work and I feel I'm missing some pieces.
This is part of the example:
client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback')
# => "https://example.org/oauth/authorization?response_type=code&client_id=client_id&redirect_uri=http://localhost:8080/oauth2/callback"
token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:8080/oauth2/callback', :headers => {'Authorization' => 'Basic some_password'})
Two quetions:
What should I do with the result of authorize_url? This url should be opened on a browser to proceed with the login, but the gem doesn't open it automatically. Should I ask the user to do so?
What about the callback URL? The example uses http://localhost:8080/oauth2/callback but is not clear if the gem itelf is in charge of listening on that port.
Any advices?
It might be easier to look at what the Quizlet API is asking you to do, and skipping the integration with the oauth gem. I could be wrong and I'd be interested to see how the the gem is used, but it's still a good idea to look at how to implement an oauth client step-by-step.
This is taken from the Quizlet API docs:
Send the user to https://quizlet.com/authorize. This can be done by displaying a link for the user to click, or redirecting server-side.
Once the user accepts/denies your oauth (this happens on the quizlet website, not your own), quizlet will send a request to your server. Because of the /authorize call, Quizlet will now have a redirect_uri which they will use to get in touch with your server. In your server's action for this route, you can get the authorization_code.
Send the authorization_code to https://api.quizlet.com/oauth/token, and in the response get an access_token whic you use for the rest of the api requests.
About the gem
You should send the authorize url to users. This is step 1 above
the gem is not in charge of listening for the redirect. You need to use a web server for this.
When doing GET /admin/webhooks.json it simply returns:
{"webhooks"=>[]}
I've created 8 webhooks using the admin panel but I can't seem to access them using the API. If I enter https://SHOP_NAME.myshopify.com/admin/webhooks.json directly into the browser it does return all the webhooks.
Here's the call I'm making using the credentials from a private app:
require 'httparty'
data = HTTParty.get("https://<API_KEY>:<PASSWORD>#<SHOP_NAME>.myshopify.com/admin/webhooks.json", :headers => {'Content-Type' => 'application/json'})
Any idea what I'm doing wrong?
Scanning through the Shopify API authentication docs doesn't give any indication that HTTP basic authentication of the form https://<API_KEY>:<PASSWORD>#... is supported.
This may be the reason why you can't query the hooks. In you browser you may use a web session. You can verify by removing the basic auth from the url and open again in you browser
https://<SHOP_NAME>.myshopify.com/admin/webhooks.json
The /admin/webhooks.json endpoint only returns the webhooks that you have registered with that API key. That's why I'm seeing an empty array.
I'm building an API with Sinatra (using Angular for the client side and want others to have access to API) and have it also be an OAuth provider. I am wondering what the best route to take (work off existing gems or roll own solution off Warden or something).
Have used devise and doorkeeper for authentication and oauth before with Rails, wondering what best solution for Sinatra is.
Ideally I don't want the views or be able to extend/mod the actions of an existing solution, as I'm interacting with it purely as an API.
I just recently did the same thing using the following answer from S/O
What is a very simple authentication scheme for Sinatra/Rack
It implies a user model, but instead of using that, I just set a user and admin password in my config file. Then I had a login form that just took a password. When the user enters that password, I checked it against the one in settings and set the session['user'] to :admin or :user according to whichever it matched (or nil if none). Then on each of my routes, I called auth: :user or auth: :admin accordingly.
APIs normally accept your login request and send you an authentication token which you need to pass back in each call. This is very similar to cookie based sessions where your browser automatically passes back the cookie which is acquired on initial website visit.
From what I've seen in Sinatra's docs, you could make a session-based authentication system like this:
enable :session
disable :show_exceptions
use Rack::Session::Pool,
key: 'session_id'
post '/login' do
user = User.login_success(params)
halt 401 if user.nil?
session[:user] = user
200
end
get '/fun' do
user = session[:user]
halt 401 if user.nil?
halt 403 if !user.has_permission_for '/fun'
"fun was had"
end
Now all you need to do in your client is to pass back the cookie token returned in response to initial visit when requesting an API function. This can be done with any web client library that supports cookie stores (such as libcurl) or by inserting the session cookie into the request header manually. Rack::Minitest functionality also supports cookies, so you can test your API with minitest.
See Sinatra API Authentication.
Quick summary:
Sinatra has no built-in auth.
It's best to build auth yourself (see the link).
There are gems available, but you probably won't need them for something as simple as an API.
I'm trying the following sample code, and failing (the uid and password I'm using are valid). Is there something I'm missing, or a simpler example I can try?
testing.rb:
require('rubygems')
gem('twitter4r','>=0.2.0')
require('twitter')
client = Twitter::Client.new(:login => 'uid', :password => 'password')
ARGV.each do |a|
#message = "#{a}"
end
status = client.status(:post, #message)
prompt> ruby testing.rb "test"
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/base.rb:120:in
`raise_rest_error': Unauthorized
(Twitter::UnauthorizedError) from
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/base.rb:125:in
`handle_rest_response' from
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/base.rb:23:in `rest_oauth_connect' from
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/status.rb:42:in `status' from testing.rb:11
#blueberryfields you will need to use the OAuth API that Twitter4R v0.5.0+ supports. This is due to Twitter.com mandating OAuth authentication as of August 2010. Supplying the login and password of your username is no longer supported either via Twitter4R, twitter.com or any other Twitter API client.
There is a fantastic tutorial on using OAuth with Twitter4R at this blog:
http://blog.monnet-usa.com/?p=342
HTH,
#SusanPotter -- Author of Twitter4R
PS Also check out #t4ruby for updates to Twitter4R
Twitter doesn't allow basic Auth (username+password) logins through their API anymore.
You should look for a method that supports OAuth-based login.
You'll need to fetch OAuth keys for your application, which can be done from the following links. The first link allows you to enroll a new application, the second one allows you to see what applications you've registered.
New Twitter Application # dev.twitter.com
Twitter Applications (Existing) # dev.twitter.com
A more in-depth guide is available at the following link. You will want to read this as OAuth requires at least two steps to authenticate before you can use the twitter API.
Authenticating Requests with OAuth
I'm trying to create a ruby-based twitter client where I can post my status from command-line using ruby. I'm trying to understand the oauth right now, and it confused me a little bit. If I'm building a web application, I can provide a callback url when the request token is complete. How would I do that from the command-line? I don't want ruby to print out the authorized and copy and paste the url and click 'Allow' to get the token. I found something about out-of-band exchange or PIN. How would I do that with OAuth library in ruby, please thank you very much.
To use the callback url mechanism, you application should be a web application. It seems you are developing desktop application and if that's the case, you should follow "PIN code" flow by supplying an oauth_callback_url of "oob" (out-of-band) when you request token. Like this,
https://api.twitter.com/oauth/request_token?oauth_callback=oob
If you properly set a header of this HTTP request (setting HTTP header is the key part of OAuth and I think you already know how to do this), Twitter will give oauth_token, oauth_token_secret and oauth_verifier. Let's call this token "request_token". You need it to get "access_token" later.
Once you have request_token, you need to open web page with the below url
http://api.twitter.com/oauth/authorize?oauth_token=request_token
This will open the authorization page and let a user to decide whether the user wants to allow your application to access his or her Twitter account. If the use says okay, then Twitter gives PIN code. You need to allow a user to type the PIN code so that you can save it.
Now, it's time to get another token ("access_token") by using your comsumer_key / secret, request_token and the PIN code. You should set header with all these values correctly and do HTTP request again with this url,
https://api.twitter.com/oauth/access_token
If Twitter accepts your "access_token" request, it will give you oauth_token, oauth_token_secret, user_id and screen_name. Let's call this token "access_token". Now, you can perform any OAuth required Twitter API by using access_token and its secret (oauth_token_secret). You can save the two values in a file and keep using them whenever you need to access the user's Twitter account. The values will be always valid until the user revokes the access to your application.
I don't know Ruby but if you know how to perform HTTP/HTTPS requests (GET / POST) with custom headers in Ruby, this PIN code flow should work fine if you follow Twitter API document carefully. Good Luck!
It will ask for the PIN code until you specify the oauth_callback when getting the request token, not when forwarding the user to the authorization url
#consumer = OAuth::Consumer.new(
TWITTER_CONSUMER_KEY,
TWITTER_CONSUMER_SECRET,
{:site=>"https://api.twitter.com"})
#request_token = #consumer.get_request_token( :oauth_callback => CALLBACK_URL )
This was the result of surfing several hours of incomplete documentation.
use Twitter gem, it will make things easier for you. http://rdoc.info/gems/tweeter/2.0.0/frames