Proxy error when using OAuth2 gem - ruby

Hi I’m trying to use oauth 2 to connect my app to a local API.
The authorization request succeed and return me a code on my callback address to make the access token request.
Here is my callback code :
def client
OAuth2::Client.new(KEY, SECRET, site: SITE, authorize_url: '/oauth2/auth', token_url: 'http://localhost:8080/oauth2/token')
end
get '/auth/callback' do
access_token = client.auth_code.get_token(params[:code], "redirect_uri" => redirect_uri)
access_token = session[:access_token] = access_token.token
#access_token = access_token
end
In get_token function, I made a pry to check my connection configuration (which is correct):
1.9.3 (#<OAuth2::Client:0x007fb255183e18>):0 > connection
=> #<Faraday::Connection:0x007fb2551817f8
#parallel_manager=nil,
#headers={"User-Agent"=>"Faraday v0.9.0"},
#params={}, #options=#<Faraday::RequestOptions (empty)>,
#ssl=#<Faraday::SSLOptions (empty)>,
#default_parallel_manager=nil,
#builder=#<Faraday::RackBuilder:0x007fb255188760
#handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp, Faraday::Response::Logger]>,
#url_prefix=#<URI::HTTP:0x007fb255187b08 URL:http://localhost:3000/>,
#proxy=#<Faraday::ProxyOptions uri=#<URI::HTTP:0x007fb255186b68 URL:http://proxy_url:port>, user="me", password=« MyPassword">>
1.9.3 (#<OAuth2::Client:0x007fb255183e18>):0 > url
=> "http://localhost:8080/oauth2/token »
1.9.3 (#<OAuth2::Client:0x007f9bdb94cce8>):0 > verb
=> :post
1.9.3 (#<OAuth2::Client:0x007f9bdb94cce8>):0 > opts
=> {
:body => {
"client_id" => "Test",
"client_secret" => "test_secret",
"code" => "d3c4661b11ea5e2752852db72e1ce100f2f1804d",
"grant_type" => "authorization_code",
"redirect_uri" => "http://localhost:4567/auth/callback"
},
:headers => {
"Content-Type" => "application/x-www-form-urlencoded"
},
:parse => nil,
:raise_errors => true
}
Debug informations from request :
I, [2014-08-20T12:01:19.450941 #12792] INFO -- : post http://localhost:8080/oauth2/token
D, [2014-08-20T12:01:19.451040 #12792] DEBUG -- request: User-Agent: "Faraday v0.9.0"
Content-Type: "application/x-www-form-urlencoded"
I, [2014-08-20T12:01:19.451203 #12792] INFO -- Status: 401
D, [2014-08-20T12:01:19.451258 #12792] DEBUG -- response: cache-control: "no-cache"
pragma: "no-cache"
www-authenticate: "NTLM, BASIC realm=\"OUR_DOMAIN_NAME\""
content-type: "text/html; charset=utf-8"
proxy-connection: "close"
set-cookie: "BCSI-CS-925062b0249dae29=2; Path=/"
connection: "close"
content-length: "706"
x-rbt-optimized-by: "riv-olo (RiOS 8.5.1) IK"
OAuth2::Error - Nice page from my proxy telling me that I’m not authentified on the domain
When I make a POST request with POSTMAN REST Client using my authorization code, everything is fine and the API return me an access_token.
I don’t understand why the request is passing by the proxy because all my apps and API are on my localhost.
Could someone tell me why this error append using my local app ?
Thanks

As my postman request worked and not those of my app, I used Wireshark to see the difference between them.
In Oauth, my proxy parameters were used by default. So my request went on the proxy IP.
And on Postman, requests went directly on localhost.
So I changed my client definition to force empty proxy parameters :
PROXY_URI = ''
PROXY_USER = ''
PROXY_PASSWORD = ''
def client
OAuth2::Client.new(KEY, SECRET, site: SITE, authorize_url: '/oauth2/auth', token_url: 'http://localhost:8080/oauth2/token', connection_opts: {
:proxy => {:uri => PROXY_URI,
:user => PROXY_USER,
:password => PROXY_PASSWORD}})
end
Now request are send to localhost as expected.
It's ok for local tests, but now I'll need to make conditional assignment of my proxy variables.
Why the GET method were sent to localhost and not POST method ? It's still a mystery !

It sounds like you're trying to hit localhost via your proxy, which won't work. If you're using OS X:
Go to System Preferences > Network.
Select the connection you're using on the left (eg. "Wi-Fi" or "Ethernet").
Click "Advanced..." at the bottom right.
Go to the "Proxies" tab.
In the box at the bottom ("Bypass proxy settings"), add 127.0.0.1, localhost.
Click "OK", then "Apply".
Once you've done that, OS X shouldn't route requests to localhost via your proxy, and Postman should work fine.

Related

HTTParty post method doesn't return status code when adding follow_redirects = false along with other headers and cookies?

The HTTParty methods are like HTTParty.XXX(urlGoesHere, and Args Here)
I'm doing the following:
params = {:UserName => "uname", :Password => "pwd"}
cookie_hash = HTTParty::CookieHash.new
cookie_hash.add_cookies("key1=val1")
cookie_hash.add_cookies("key2=val2")
options = {
:body=>params,
:headers => { 'Cookie' => cookie_hash.to_cookie_string,
'Accept' => something },
:follow_redirects => false
}
URLUserNamePwd = HTTParty.post(myURL, options) # Is this the right way to do?
When I check the http status code, body I get nothing. When I check in the browser development console, I see 302 redirect, and in response headers I see lot of header pairs returned.
What is the URL you're attempting to hit? 302 Found will be paired with a Location header containing the URL where the resource can be found.

Post request detected as bot with HTTPARTY but not with postman (same headers)

I am trying to fetch a public API. When I do it from the postman everything works fine however when I do it from my app I get and error message: <META NAME=\"robots\" CONTENT=\"noindex,nofollow\"
I do not understand how this is possible?
Here is are the headers variables I adjust when I make my request with postman:
Cookie:"some cookie"
Cache-Control: no-cache
Content-Type:application/json
Host:"some host"
Here is my httparty request:
response = HTTParty.post(url,
:body => body_request (same as with postman),
:headers => {
'Content-Type' => 'application/json',
'cookie' => 'same cookie as above',
'Host' => 'same host as above',
'Cache-Control' => 'no-cache'
}
)
Why would it work with postman but not with a httparty request?
Thank you
I would look into User-Agent, even if you don't explicitely set the header, your http client is still sending one.
Postman uses :
"User-Agent": "PostmanRuntime/7.26.8",
while HTTParty is simply
"User-Agent": "Ruby"
Maybe your public API (could be more precise if we knew which) has a whitelist of 'non-bot' user agents and HTTParty is not among them
Try overriding it
resp = HTTParty.get 'https://httpbin.org/headers' , headers: {'User-Agent': 'xx'}

How to use Typhoeus::Request object using https

I'm trying to make an https request using the Typhoeus::Request object and i don't get it working.
The code i'm running is something like this:
url = "https://some.server.com/"
req_opts = {
:method => :get,
:headers => {
"Content-Type"=>"application/json",
"Accept"=>"application/json"
},
:params=>{},
:params_encoding=>nil,
:timeout=>0,
:ssl_verifypeer=>true,
:ssl_verifyhost=>2,
:sslcert=>nil,
:sslkey=>nil,
:verbose=>true
}
request = Typhoeus::Request.new(url, req_opts)
response = request.run
The response i'm getting is this:
HTTP/1.1 302 Found
Location: https://some.server.com:443/
Date: Sat, 27 Apr 2019 02:25:05 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Why is this happening?
Well it's hard to know because your example is not a reachable url. But 2 things I see is that you are not passing an ssl cert or key. But also 302 indicates a redirect. You can try to follow redirection but your first problem is probably you don't need to set SSL options, why are you?
See if you try the following options:
req_opts = {
:method => :get,
:headers => {
"Content-Type"=>"application/json",
"Accept"=>"application/json"
},
:params=>{},
:params_encoding=>nil,
:timeout=>0,
:followlocation => true,
:ssl_verifypeer=>false,
:ssl_verifyhost=>0,
:verbose=>true
}
See the following sections for more info
https://github.com/typhoeus/typhoeus#following-redirections
https://github.com/typhoeus/typhoeus#ssl

Google Signin from server side app in ruby

I have a mobile app that is signin in with google and sending a server auth code to my backend app.
I want to use this code, along with the client secrets from the google developer console, to retrieve a refresh code for retrieving data from google drive when the user is offline.
Google provides an client for auth calls in ruby, but it seems not to be maintained lately and I could not see a way to do this kind of authorisation in the docs.
In the documentation, I could find an example of how to do this on python:
from oauth2client import client
# Exchange auth code for access token, refresh token, and ID token
credentials = client.credentials_from_clientsecrets_and_code(
CLIENT_SECRET_FILE,
['https://www.googleapis.com/auth/drive.appdata', 'profile', 'email'],
auth_code)
I would like to do this in ruby through a post to their https://www.googleapis.com/oauth2/v4/token endpoint. Here is what I've tried so far:
require 'uri'
require 'net/http'
require 'json'
url = URI("https://www.googleapis.com/oauth2/v4/token")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
headers = {'Content-Type': 'application/json'}
request = Net::HTTP::Post.new(url.request_uri, headers)
request.body = {
code: "#{server_auth_code_sent_to_api}",
client_id: "#{client_id_from_developer_console}",
client_secret: "#{client_secret_from_developer_console}",
grant_type: 'authorization_code',
redirect_url: '',
}.to_json
response = http.request(request)
puts JSON.parse(response.read_body)
But I keep getting the following error:
{
"error": "unsupported_grant_type",
"error_description": "Invalid grant_type: "
}
Does anybody has an idea on what I'm doing wrong, or has a working example on how to do this kind of authorisation?
Thanks in advance.
In case somebody stumbles here with a similar problem, what caused the request to fail was the Content-Type, and not the grant_type parameter.
Digging around in the code for the client library I saw that they use application/x-www-form-urlencoded the endpoint expects a application/x-www-form-urlencoded content type. I adjusted my code accordingly and was able to get a successful response with the valid credentials and token.
Here follows the resulting code:
require 'uri'
require 'net/http'
require 'json'
url = URI("https://www.googleapis.com/oauth2/v4/token")
params = {
"code" => "#{server_auth_code_sent_to_api}",
"client_id" => "#{client_id_from_developer_console}",
"client_secret" => "#{client_secret_from_developer_console}",
"grant_type" => "authorization_code",
"redirect_url" => "#{redirect_url_from_developer_console}",
}
response = Net::HTTP.post_form(url, params)
puts JSON.parse(response.read_body)

"Error validating client secret." 404 with Facebook Oauth and ruby

I am trying to implement facebook authentication for an app with warden, after the user allows facebook auth and redirects to my app callback with the token I get a 400 while consuming the api. My warden strategy is this:
class Facebook < Warden::Strategies::Base
def client
#client ||= OAuth2::Client.new MyApp::Facebook::AppID, MyApp::Facebook::AppSecret, :site => 'https://graph.facebook.com'
end
def params
#params ||= Rack::Utils.parse_query(request.query_string)
end
def authorize_url
client.web_server.authorize_url :redirect_uri => request.url, :scope => 'email,publish_stream'
end
def authenticate!
throw(:halt, [302, {'Location' => authorize_url}, []]) unless params['code']
facebook = client.web_server.get_access_token params['code'], :redirect_uri => request.url
rescue OAuth2::HTTPError => e
puts e.response.body
end
end
Strategies.add :facebook, Facebook
The result of printing the response body is this:
{"error":{"type":"OAuthException","message":"Error validating client secret."}}
I am pretty shure the app id and app secret are the ones provided by FB.
Thanks.
I've seen that error message many times. Here are the things I would double check:
your domain is the same as what you listed in the facebook callback url
the app id is correct (actually print this out on a page, sometimes y
the app secret is correct
Add redirect_uri while creating the object of facebook that will fix the issue.
Redirect the user to https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL
After user click allow, it'll hit our Redirect Uri
At that point we'll get the code and we need to do a server side HTTP Get to the following Url to exchange the code with our oAuth access token:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
Now at step 3, I kept on getting Http 400 response back.
So after some research, I found out that on that redirect_uri that we submitted on step 3 doesn't do anything but validate the request. Thus, the value need to match with step 2.
I also get the same error and i resolved by doing as below:
double check your client_id, client_secret, redirect_uri.
Add Accept: "application/json" header to thye request
fetch(
`https://graph.facebook.com/v15.0/oauth/access_token?client_id=${process.env.FACEBOOK_APP_ID}&redirect_uri=${process.env.FACEBOOK_REDIRECT_URI}&client_secret=${process.env.FACEBOOK_APP_SECRET}&code=${code}`,
{
method: "GET",
headers: {
Accept: "application/json",
},
}
)

Resources