This problem has puzzled me for a few days, and I think I've finally narrowed it down. I'm using the Facebook JS SDK to do client side authentication:
FB.login(function(response) {
if (response.authResponse) {
var url = "/auth/facebook/callback?redirect=";
url += '&' + $.param({ signed_request: response.authResponse.signedRequest });
window.location = url;
}
}, { scope:'email,publish_stream,publish_actions' })
Note that I'm manually passing in the signedRequest. For some reason when I don't, I get an error that complains that there must be a 'code' parameter or a signed request (OmniAuth Strategies Facebook NoAuthorizationCodeError (must pass either a `code` parameter or a signed request (via `signed_request` parameter):). This is with omniauth-facebook gem version 1.4.0. If I use the latest of 1.4.1, I get the invalid_credentials issue that everyone else seems to be getting.
When I try to log in, something strange happens. I turned on my Chrome debugger, switched to the Network tab. I see two network requests, both GET to
https://www.MYHOST.com/auth/facebook/callback?redirect=&signed_request=BIGSTRINGHERE
However, interestingly the first request has a status of 301 and the second has a status of 302, and the next network request is to the /auth/failure callback. To make things more puzzling, this doesn't reproduce locally, only in production. Locally, it works and only does a single request, which has a http status of 302.
Also it's worth noting that after hitting the failure callback, it returns to my website homepage, which then triggers the autologin feature because it detects the user is a FB user and has an account on the site. This piece of code hits the same callback url and succeeds.
So my question is why is there a second request to the callback and how do I get rid of it to presumably get the login to work correctly? Bonus question is why do I have to manually pass along the signedRequest when tutorials don't seem to have to do this (e.g. RailsCast #360)?
A few notes to clarify and provide details:
I am using omniauth-facebook 1.4.0, omniauth 1.1.4, and omniauth-oauth 1.0.3
I am not using Devise. I also don't seem to be initializing the facebook omniauth more than once.
This issue only happens locally and not in production using the same Facebook app ID and secret. The login url is set to a production domain and I use some local configurations to get production domains to point locally.
The appID and secret are correct (the autologin works, and it works locally).
The Facebook app is not in sandbox mode.
Turns out the issue was that the callback that was redirected to was https. Since that page wasn't available in https, it redirected to http, resulting either in a loss of data or bad data. I failed to notice that the second request was http and not https. Enabling ssl for that callback action fixed the issue.
Related
I have a Single Page App using Auth0 Implicit Flow with Silent Authentication. I got the authentication part working just fine, but when I try to implement checkSession method to renew the session in the background (as per https://auth0.com/docs/libraries/auth0js/v9#using-checksession-to-acquire-new-tokens), the AJAX call to the auth0.com domain returns a 400 HTML error instead of a JSON one.
webAuth.checkSession({}, function (err, authResult) {
...
});
The error is Oops!, something went wrong, which I can see in my browser devtools Network Response tab.
There could be a misconfiguration in the system or a service outage. We track these errors automatically, but if the problem persists feel free to contact us.
Please try again.
I am not sure why there would be an HTML response, and not sure what I might be doing wrong. I have added my page's domain to the "Allowed Web Origins" list on the Auth0 application settings.
What I was missing was providing the redirectUri parameter to the checkSession call.
I also found out that I could find logs to these errors by going to the "Logs" menu on the Auth0 dashboard.
Everything was working fine and Omniauth has stopped working suddenly. I didn't make any code changes.
I checked Twitter Apps Settings:
I have callback url to my main production url, and Callback URL Locked to No. All keys are correct.
Any idea? 🤔
OAuth::Unauthorized
403 Forbidden
I have been able to solve it (also for development) adding this urls:
For production:
https://mydomain/users/auth/twitter/callback
http://mydomain/users/auth/twitter/callback
For development:
http://localhost:3000/users/auth/twitter/callback
Now on twitter callback URL, you must have to add 2 callback URLs and the callback URL must be the path of your application.
I had faced the same problem, now on adding the 2nd callback URL, it's fixed.
For more information check: https://twittercommunity.com/t/action-required-sign-in-with-twitter-users-must-whitelist-callback-urls/105342
Adding a second Callback URL to https://mysitecom/auth/twitter/callback fixed the issue (for now)
———-
Update: This actually solved the problem for about 10mins. Experiencing the same problem now
I'm working in development not production and encountered this problem using the omniauth and omniauth-twitter gems. But with these two callback URL's:
http://127.0.0.1:3000
http://localhost:3000/auth/twitter/callback
the problem is avoided. Strange, since the RailsApps tutorial warns against using 'localhost' at Twitter.
This is almost certainly related to this change: Action REQUIRED - Sign in with Twitter users must whitelist callback URLs.
From the link:
In 30 days, we will begin enforcing the whitelist such that any URL
not added to the whitelist will fail. This means that URLs can no
longer be programmatically overridden in calls to the
oauth/request_token endpoint 112. The callback_url parameter provided
must match one of the whitelisted callback URLs. While we generally
provide longer than a 30-day notice for changes like this, this
timeline allows us to continue to provide a safe and secure experience
for developers and our users.
You can add callback URLs to your whitelist on the applications
settings page on apps.twitter.com 488.
Enable the setting “Enable Callback Locking” to test that only URLs
you have whitelisted are accepted. Callback URLs will automatically be
locked and the whitelist will be enforced starting on June 12th. The
“Enable Callback Locking” setting will be removed on this date.
I could not get this to work in development with 127.0.0.1 so I ended up creating a DNS A record that pointed to 127.0.0.1 (e.g., dev.example.com) and used that in the callback url settings on https://apps.twitter.com.
Unicode domain name. Twitter give me error: unsupportable domain name format. I need exactly match callback url, sending by my server and callback url in my twitter app.
Solution:
config/initialization/twitter.rb
OmniAuth::Strategies::Twitter.class_eval do
def callback_url
return my_custom_twitter_app_callback_url_string_variable
end
end
I just resolved the issue by putting https://domain/oauths/callback in the Callback URLs list. Make sure you enable the callback locking option.
I have a Rails 5 (Ruby 2.3.3) app with OmniAuth (1.6.1; omniauth-oauth 1.1.0) and omniauth-twitter (1.4.0). When a user is directed to Twitter for the OAuth flow, they see the following error after tapping the "Authorize application" button:
Whoa there!
There is no request token for this page. That's the special key we need from applications asking to use your Twitter account. Please go back to the site or application that sent you here and try again; it was probably just a mistake.
The most unfortunate problem about this error is it doesn't happen locally—I have a an identically configured app in Twitter's app management console, save for a different URL (127.0.0.1 for the local app, a Heroku URL for the server).
Additionally, we have other OmniAuth strategies that work without issue locally and in production.
Verify that your system clock is set correctly and that all of your keys are entered correctly. Ensure you're using the right paths (api.twitter.com/oauth/*) and make sure that you're actually sending a request token to the oauth/authorize page and not an access token.
I have a phonegap app which connects to a web service and authenticates using http basic authentication. It is built using phonegap build and targets Android and iOS.
On a login view, an ajax request fires against the remote server to check if credentials are correct, then if so, logs the user in to the main application.
This completes successfully in ripple emulator on desktop pc and when also when deployed onto an Android device.
However, when the app is deployed onto an iOS device (ipod touch) the authentication request simply does not ever complete. Using phonegap remote debugger I can see that the ajax request starts but never completes. It is always in a pending state. I use jquery ajax success, error and complete handlers for the request, but none of them are ever hit so I don't get the chance to see any error messages returned from the server. The request never seems to complete.
I have tried making ajax requests to other remote web sites to test that my app can communicate and they succeed, so it doesn't seem as though I have white-listing issues.
Any ideas of what the issue could be?
Please read the update to this answer at bottom.
Original answer
I have found what the issue is and managed to get basic authentication working.
The issue was that the web server was expecting basic authentication details to be preemptively sent with the request.
To do this use the 'headers' property of jquery ajax as shown below:
$.ajax
({
type: "GET",
url: "https://webserver/authenticate",
headers: {
"Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
}
})
.done(function(){
alert('Authenticated!')
})
.fail(function(){
alert('Error!')
});
See related answer:
https://stackoverflow.com/a/11960692/1463497
Update
I found in the end that there is no reliable way of using basic authentication in a web view in iOS. I.e everything is fine if correct credentials are entered but when they are not and the 401 challenge response comes along, iOS web view can't seem to handle it.
In the end, the web service authentication was implemented by simply passing 'username' and 'password' parameters as part of the url:
url: "https://webserver/authenticate?username=abc&password=123"
This is the only consistent way I found of getting authentication to work across iOS and Android in a web view (by getting rid of basic authentication altogether). This of course meant updating the web service itself to accept authentication in this way.
I am using the ruby twitter gem and oauth to gain access to users twitter accounts. In my code, I have:
unless #user.twitter_authd?
oauth = Twitter::OAuth.new('token', 'secret')
session[:twitter_request_token] = oauth.request_token.token
session[:twitter_request_secret] = oauth.request_token.secret
#twitter_auth_url = oauth.request_token.authorize_url
end
where token and secret have my actual token and secret inserted. When I click on the link to the #twitter_auth_url, I am taken to twitter and asked to grant access. I click allow and then twitter redirects me to my callback URL http://www.mydomain.com/twitter_callback/?oauth_token=fmy2aMvnjVgaFrz37bJ4JuB8r5xN79gsgDQRG4BNY which then hits this code:
oauth = Twitter::OAuth.new('token', 'secret')
logger.info("session[:twitter_request_token] = #{session[:twitter_request_token]}")
logger.info("session[:twitter_request_secret] = #{session[:twitter_request_secret]}")
oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])
session[:twitter_request_token] = nil
session[:twitter_request_secret] = nil
#user.update_attributes({
:twitter_token => oauth.access_token.token,
:twitter_secret => oauth.access_token.secret,
})
redirect_to root_path
The twitter request token and secret are being set just fine. However I end up with an authorization error:
OAuth::Unauthorized in MainController#twitter_callback
401 Unauthorized
RAILS_ROOT: /Users/TAmoyal/Desktop/RoR_Projects/mls
Application Trace | Framework Trace | Full Trace
/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/consumer.rb:167:in `token_request'
/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/tokens/request_token.rb:14:in `get_access_token'
/Library/Ruby/Gems/1.8/gems/erwaller-twitter-0.6.13.1/lib/twitter/oauth.rb:29:in `authorize_from_request'
/Users/TAmoyal/Desktop/RoR_Projects/mls/app/controllers/main_controller.rb:70:in `twitter_callback'
The code is failing at this line:
oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])
when it tries to get an access token. You can see the source code of authorize_from_request here. I am not sure why this is happening. Anyone have ideas?
A bit late to the party but just ran into the same issue myself. I tracked the issue down to the setup of my OAuth app in Twitter. I had initially not specified a callback URL as I was unsure of it.
Once I had setup my rails app I went back to find Twitter had assumed I was a desktop application as I hadn't specified a callback URL. Once I changed this to website and entered a callback URL I stopped getting 400s.
If you're getting error 401 - OAuth::Unauthorized, make sure you edit the settings of your Twitter application as follows:
Application Type: Browser
Callback URL: http://127.0.0.1:3000/auth/twitter/callback
this is an issue about time synchronization of your system with twitter server.
Twitter doesn't allow localhost as part of a valid callback URL.
Instead use http://127.0.0.1:3000/auth/twitter/callback
Hope this helps
This was one of the most annoying things to debug that I have come across. I was outputting in a couple places by accident because the URL's are dynamic and they happened to not be defined in my test case (i use this to display chart data and there is not enough right now so the google chart api URL's are blank). This caused my browser to make multiple requests to my localhost when some pages were loaded. Somehow that made the oauth process crap out. Obviously there is no way for people on S.O. to know about my application specific issue so I had to answer my own question.
I had this same problem and none of the suggestions in this thread worked for me.
I found the problem for me was the TIMESTAMP on my request. The mobile device I was running my scripts on had a jacked up clock. When I updated the system time on my device to the correct time (i.e. now), all of my requests came back "200 OK" instead of "401 Unauthorized".
This problem seems to be caused by twitter not being able to handle connection keep-alive correctly. Make sure you set connection=close http header in the request to twitter. Wasted a weekend debugging this.
not enough info for me, but when was twitter gem last updated? twitter changed their oauth 'stuff' in mid may approx. perhaps you have an old one. I'd update your question to show the callback_url, and make sure you have the right token and secret, which it looks like you don't have.
also, did you put the right callback url in your twitter app page? alot of times that screws you up too.
if that fails use mbleighs twitter_auth instead. it worked for me and is pretty slick.