I'm getting a facebookexternalhit UserAgent during our OAuth login redirect.
This is causing exceptions, because it tries using the FB OAuth token - luckily it already has been used by the user.
It's hitting an url like:
/auth/fb/login-with-redirect?redirectUrl=https%3A%2F%example.com%2Fnl&code=AQCwC2...YPe
Anyone else experiencing this?
Is there any legit reason for FB to do this? Like checking for spam or whatever?
I'm now sniffing out the facebookexternal hit useragent and just early return an empty page. Can this cause problems?
Related
What I am using OAuth to authenticate with Microsoft:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize...&redirect_uri=MYURL
(I also use similar approach with google: https://accounts.google.com/o/oauth2/v2/auth...redirect_uri=MYURL)
MYURL is https://admin.myrealdomain.com/code
(MYURL is an empty 200 Ok page on my server)
However, Microsoft Graph returns with 302 redirect from https://login.live.com/oauth20_authorize.srf...
and this causes issues with deeplinks handling (the page just is not intercepted by the app).
I don't have any such issues with Google though (200 status code).
And it seems like it recently worked just fine with Microsoft as well. I am just not sure if this is something I miss or MS has some recent changes applied to that logic.
Does anyone has any idea how I can solve it? Thanks!
It seems that you are executing the OAUTH code flow behind the scenes. It doesn't work this way.
You should pop up a browser dialog to request the authorization code. See reference here.
The steps:
Pop up a browser dialog which the url address is
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?...
After User signs in, it redirects to the redirect url, where the
authorization code has been returned.
POST to
https://login.microsoftonline.com/common/oauth2/v2.0/token?....
you can get the access token to call Microsoft Graph API.
I want to publish my first Facebook application and a Privacy Policy URL is required.
I have the page privacypolicy.html published in my website but I get the next message when I configure it in "App Details":
You must submit a valid Privacy Policy URL in order to be compliant with Facebook Platform. Request failed with error:
Bad Response Code: URL returned a bad HTTP response code.
The http code returned when I request the page is 200
Any ideas?
The URL is cached by facebook.
Adding # at the end of my Url did the job ..
This is an old question I know, but I figured I'd post my solution and hope it helps anyone. For me I got this error because I had rewrite rules that didn't catch the URL that Facebook actually goes to in order to get the privacy policy. Facebook adds a query string to the URL that you give it for the privacy policy and since my privacy policy page doesn't do anything with the query string, I didn't check for it in my rewrite rule.
You can check out how Facebook scrapes the page you give it by going to Facebook's Sharing Debugger and putting your URL in the input bar. You can also see the last time that Facebook tried to scrape that URL and tell Facebook to try again once you've fixed any issues. This will get around the caching that was mentioned in user2390340's post.
Facebook externalhit appears to request via the ipv6 address published in DNS if there is one available and won't check on the ipv4 published in DNS.
If your website doesn't have ipv6 enabled it'll return a 404 or 500 and you'll get that error "Bad Response Code: URL returned a bad HTTP response code" for your Privacy Policy URL.
Edit:
Also noted that Facebook caches the URL, I was checking it and getting a "bad response code" error even though there was no hit from their UA in the access logs.
Adding ?stuff onto the end of the URL in the Privacy Policy field bypassed a cache and the access log hits showed up with 200 OK, allowing the URL to be saved.
Not sure if this is related to user2259887's comment about Facebook using IPV6 DNS. But after reading his comment, I was able to work around the validation issue by specifying an IP Address URL instead of using the host domain name URL.
This workaround will not work well if the site IP address is dynamic or change often.
I'm using FB.login on the JS client and want to verify the user's identity on the server. So, the client gets a signedRequest from facebook and sends it to the server. The server splits on the period, and decodes the second part of the signedRequest into a json object.
What should I be using for "code" when I send my server-side request to
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&redirect_uri=YOUR_REDIRECT_URI
&client_secret=YOUR_APP_SECRET
&code=CODE_GENERATED_BY_FACEBOOK
My decoded json looks something like:
{"algorithm":"HMAC-SHA256","code":"2.AQCPA_yfx4JHpufjP.3600.1335646800.1-5702286|l11asGeDQTMo3MrMx3SC0PksALj6g","issued_at":1335642445,"user_id":"5232286"}
Is that the code I need? Does it need to be B64 encoded? If this isn't the code, what code should I use?
_
What I've tried:
The request I'm trying to use is:
https://graph.facebook.com/oauth/access_token?client_id=295410083869479&redirect_uri=https://squaredme.appspot.com/facebookredirect&client_secret=44f1TOPSECRETbb8e&code=2.AQCPA_yfx4JHpufjP.3600.1335646800.1-5702286|l11asGeDQTMo3MrMx3SC0PksALj6g
but this returns the error:
{"error":{"message":"Error validating verification code.","type":"OAuthException","code":100}}
I can't tell if this is because I'm using a bad code, or what. Noteably, this is running on my local dev server, and squaredme.appspot.com definitely does NOT resolve to my IP. I don't know if facebook checks that or what - I'm assuming I'd get a better error message. Thanks for any direction!
You are trying to somehow combine the two flows together and that's why things don't work well.
When facebook POSTs into the iframe with your app url and a signed request there are two options, the easy one being that the user is already authenticated and then the signed request will have all the necessary data (including a signed request), then you just load the canvas page and use the JS SDK to get an access token there as well, but in this case there's no need to use the FB.login (since it opens a popup and will automatically close it), you can use the FB.getLoginStatus method which won't annoy the user.
If the user is not authenticated then the sign request will be missing the things you need to use the graph api.
You then redirect the user to the auth dialog, and since you are loaded in an iframe you'll need to return a html response which redirects the parent window using javascript, like:
top.location.href = "AUTH_DIALOG_URL";
When the use is done (accepted or rejected the app) he will be redirected to the "redirect_uri" you added as a parameter to the auth dialog.
If the user accepted your app then you'll be getting the "code" parameter in the query string.
You then take the code, exchange it with an access token as you posted in your question, and then redirect the user back to "apps.facebook.com/YOUR_APP".
When the page then loads the user is already authenticated and you'll be getting a full signed request.
I hope this clarifies things for you, recheck the Server-Side flow it pretty much covers it all.
I also had some trouble with that, then I found the solution here in StackOverflow.
There are two kinds of "code" provided by facebook. One comes inside the signedRequest in the cookie generated by the client-side flow. The Facebook's JS SDK handles this codes and get a access token without telling us anything.
The other type of code comes attached as a query to your redirect URI (http://www.yoururl.com/index.php?code=AAAgyiaus...), when you navigate to OAuth URL (server-side flow). With this code, you go to a Token URL and get your access token.
When you are using the server-side flow, you need to indicate a redirect URI both in the OAuth URL AND in the Token URL, and they have to be exactly the same, so a missing slash or a query string can be a lot of problem.
The codes are different from each other. When you use the both things together, appears to be impossible to get a access token using the code that was inside the cookie's signedRequest.
BUT, it is not. The magic is: the code from signedRequest is associated with NO URI, so as long as the redirect_uri is a mandatory field, all you have to do is to pass it blank when you navigate to the Token URL.
So the final solution is: grab the signedRequest from the cookie, parse it in your server to obtain the code, then read the Token URL:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&redirect_uri=&client_secret=YOUR_APP_SECRET
&code=CODE_INSIDE_THE_SIGNED_REQUEST
It looks like a hack, so I don't know how long it's gonna work, but it's working right now.
I'm trying to pass some variables to my facebook app from the url, i.e. using GET variable app_data like facebook wants.
At some point I've stopped getting the ['signed_request'] part of the $_REQUEST. When I print_r($_REQUEST) I'm getting: ['doc'], ['user'], ['__utmz'], ['__utma'] and ['session'] values, but not signed request :(
Any ideas of why this might be happening?
Check the tab/canvas url is EXACTLY the same as required. If there is a redirect to another page, then signed request and other values will not be sent. You can check using a browser sniffer, if a call to the page responds with a 300 (301/302 etc) redirect, then you need to change to what it redirects to.
Examples:
https://example.com/ may need to be https://www.example.com/ (add www., or remove www. depending on how server is set up)
www.example.com/ may need to be www.example.com/index.php (add index.php, or the right page).
Check you are using http:// and https:// correctly in the URLs, and that https:// returns a valid page.
I've only been able to get the signed request in https://, i get no request at all in http.
Currently have a bug on FB, but no word on fixing it yet; http://developers.facebook.com/bugs/264505123580318?browse=search_4eb3ef23eb18d6649415729
EDIT:
http://SITE.com was redirecting to http://www.SITE.com, so I was loosing the request variables.
Had a similar issue, for me it was as simple as a mismatch of the app id and app secret! However in facebook developers backend I have noticed that the URLs all need to have that trailing slash!
Some browsers do redirect your request to https automatically if you have been on this particular site on https so if you are in http mode on facebook there is situation:
facebook requests http version of your app, browser redirect this request of facebook to https and POST data and thus signer_request are gone in this process...
i see this problem in chrome 23, if you delete browsin data (particulary Deauthorize content licenses) app should run back on http
I am using java and the purpose of my demo application is simple: Update user status.
I followed the Server-side Flow on page http://developers.facebook.com/docs/authentication. I got the auth dialog, facebook lead to the callback url and I got the code in my callback page. Then I failed when I try to generate an access token.
In the guide page, it says the following url could be used to generated an 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
But what happens in my environment is I got the following error message:
{
"error": {
"type": "OAuthException",
"message": "Error validating verification code."
}
}
I am quite sure every parameter is correct because if I change the client_id value or client_secret parameter, I will got a different error message. The code parameter is what I got from facebook callback. So this should be correct, right? Really can't figure out what is the problem....
Any idea about this? I get stuck here...
I recently dealt with exactly this problem: everything matched, but it failed with the OAuthException. The thing that made it work was to change the redirect uri (in both requests for the flow) from:
http://foo.example.com
to
http://foo.example.com/
I.e., add the trailing slash. And then it worked. Stupid and silly, but there you go.
I had the same problem and tried the above suggestions. They helped, but in my case the problem was that my redir URL had a query parameter and Facebook wasn't cool with that. So, moral of the story is that the redir url you sent to exchange the token has to be identical the the original redir url and it can't have query parameters.
We had some fun with this as well.
In our case the trailing slash in the URL was already there, so I tried the Token we were using in the FB Debug Tool and it validated, so it looked like FB wasn't even seeing the Token in the request.
After some investigation I found the head-slapper - we doing a GET with HTTP Headers only not with a Querystring, so FB litterally wasn't seeing the Token at all.
The moral seems to be that if you can get the Token to validated in the FB Debug tool, there is likely /something/ amiss in your request -
It might be a missing "/" or some other mismatch with the App's defined URL (Domain mistmatch is a different error). I have not tried defining the App / Web Url for HTTPS and doing the request with HTTP but I suspect it would also hiccup somehow.
Or as in our case, the Request Method might be incorrect - GET with Headers or POSTing both throw the 2500, you have to do GET with a Querystring.
Hope that helps!
I had the same problem. It was a URL difference, but unlike the others that have posted, mine was the difference between HTTP and HTTPS.
We have BigIP handling HTTPS requests and forwarding over to an HTTP Apache server. When BaseFacebook's getCurrentUrl() function was called, it detected HTTP, and not the original HTTPS. I've modified that function like so:
protected function getCurrentUrl() {
if ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1)) ||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ||
(isset($_SERVER['HTTP_PSEUDOSSL']) && $_SERVER['HTTP_PSEUDOSSL'] == 'true')) {
$protocol = 'https://';
}
else {
$protocol = 'http://';
}
...
This version supports the HTTP_PSEUDOSSL key. I hope this helps someone.
Yes, the trailing slash worked for me too, thanks!
For debugging purposes, I found it helpful to use exactly the code fb provides on the developer page:
http://developers.facebook.com/docs/authentication/
Once you get that working, you can modify it to fit your own code.
I'm not sure, but you might also check to make sure your "Site URL" and "Site Domain" settings are correct on the App Edit screen, because according to the documentation, the redirect_uri must be in the same domain. (This is different from the canvas/tab page urls.)
I was also having a url problem, but the solution to it is different. I was passing the signedRequest that the JavaScript SDK returns to the server, and using the code value from that to request an access-token. However, according to some comments in the 3.1.1 version of the Facebook PHP SDK, the JavaScript SDK associates the code with a redirect_uri of empty string, i.e. "":
// the JS SDK puts a code in with the redirect_uri of ''
if (array_key_exists('code', $signed_request)) {
$code = $signed_request['code'];
$access_token = $this->getAccessTokenFromCode($code, '');
if ($access_token) {
// etc
}
}
After I changed my own server-side code to use a redirect_uri of "", then the request for an access-token worked.
in my case, my code wasn't working on IE.
The issue was in the following line
$user_id = $facebook->getUser();
if ($user_id)
Because somehow the getUser function always returned 0, so that condition was always true. Than he generated that error from invalid token.
Well, i fixed it by just saying this:
if ($user_id>0)
Silly stuff...