I've installed the Android app on facebook developer app page, set everything in the same manner as for the app for which there was no such error. Opening for Facebook login the exact same URL that works for the other app:
"https://www.facebook.com/v2.8/dialog/oauth?
client_id=myClientId
&scope=publish_actions
&response_type=granted_scopes &redirect_uri=https://www.facebook.com/connect/login_success.html"
);
I've added https://www.facebook.com/connect/login_success.html to the Valid Oauth URIs in my app settings of course. My app has everything set the same way for both apps, except for their package names, yet for this one I get 'URL blocked: This redirect failed because the redirect URI is not whitelisted in the app's Client OAuth Settings.' But it is!
So I don't understand, obviously Facebook sends me the wrong error message so it's impossible to figure out where's the bug.
I've solved it by waiting about an hour and trying again. So apparently this is not mentioned in the docs anywhere but it can take really long before a new Facebook app gets registered and until then no URI can be whitelisted. This means if you just added your app and you're getting this error message no matter what you've tried of the dozens of suggestions you find on the web, it's most likely not your fault, just wait. I wish I knew this before trying all those things.
I am building a frontend client for Jira and am running into some conflicting authentication methods I think.
I have setup the OAuth2 authentication method for logging in and hitting the Jira API. I have a button on a login page that redirects to Jira, you log in, hit "allow" and are redirected to my app. This step completes fine, I have a token and a secret and can make api calls just fine.
Next, I make an api call to get the user data, which returns fine. One of the pieces of data is a set of avatar urls. I put one of the urls into my site's markup. Here is where the problem begins.
If my browser session that I used to login is still active, I get an avatar. BUT if not, I get an "anonymous" avatar from Jira.
All the while, my OAuth token/api calls all seem to return fine.
This makes sense as Jira is using cookie based auth and I am not. So if that cookie dies in my browser, the call to the image will fail.
My ultimate question is how to handle this? Is this my responsibility to put an expiration on the token? What happens if they select "Stay logged in"? I don't think I get that knowledge on the OAuth side.
I kind of feel like I am missing something but I cannot figure out what. This seems like a problem that has been fixed or isn't even really a problem.
One solution would be just to switch to a cookie based authentication but OAuth seems more secure.
I've also tried directly hitting it from my server but that also yields an anon avatar. As does a curl with the access token. Maybe I didn't provide it in the correct way?
Any thoughts or ideas on this would be greatly appreciated. Thanks in advance.
How can I setup PAW to work with Facebook locally for development? Or even at all for that matter?
I have a node.js backend that I'm setting up with Facebook Auth. Every one of my routes needs the user to be logged in. I have two endpoints related to FB Auth. localhost:3000/api/v1/loginFB and localhost:3000/api/v1/callbackFB. Both of these work great in a web browser.
loginFB simply returns this string... https://www.facebook.com/dialog/oauth?client_id=523534457345&redirect_uri=https://localhost:3000/api/v1/callbackFB&scope=email,public_profile,user_friends.
When I call that URI in a browser, it returns a code=blahblah which my callbackFB endpoint uses to fire off another request to get the access token. All good.
So now in PAW I'm confused by the difference between the request URI and the Authorization URL text field? Should I use the loginFB URI for my request URI? And then https://www.facebook.com/dialog/oauth in the Authorization URL textfield?
Basically what's happening is that when I click Get Access Token, it returns the code but my callbackFB endpoint 500's by saying "This authorization code has been used." The code that it's getting returned is definitely different each time I Get Access Token.
This is where I'm at with this thing (Client ID and Client Secret are actually my App ID and App Secret from fb's dev management site, and the Access Token URL is actually set to https://graph.facebook.com/v2.3/oauth/access_token which I'm 99% sure is the correct URI):
This is the error I get when I click Get Access Token button:
It would be awesome to get some advice from anyone with experience with this issue. Thanks.
Re: #MichaMazaheri
tl;dr Fixed in version 2.2.2
Sorry for the super late follow-up. We actually fix this exact issue in Paw 2.2.2, which is already released on our website, and pending review for the Mac App Store. (It was some JSON vs. Form URL-Encoded parsing issue). Thanks for reporting.
I'm using server side authentication for Facebook detailed on this page.
https://developers.facebook.com/docs/howtos/login/server-side-login/#step5
I'm asking for extended permissions like user_birthday and if the user accepts, I get the code
YOUR_REDIRECT_URI?
state=YOUR_STATE_VALUE
&code=CODE_GENERATED_BY_FACEBOOK
But if let's say the user declined to provide birthday, I still want to proceed when I get this url
YOUR_REDIRECT_URI?
error_reason=user_denied
&error=access_denied
&error_description=The+user+denied+your+request.
&state=YOUR_STATE_VALUE
Does anyone know how to get the code under that scenario or do I have to ask the user to signin again but this time not asking for additional permissions?
Cheers,
Steve
Does anyone know how to get the code under that scenario or do I have to ask the user to signin again but this time not asking for additional permissions?
There are two scenarios here:
You are asking the user to connect to your app for the first time. At this point, they can not decline giving you user_birthday permission solely (since it’s a basic and not an extended permission) – they either connect to your app, or they don’t.
The user has connected to your app before, and now you are asking for user_birthday permission. If the user declines that, that will lead to the error_reason=user_denied – and then you will not get a code parameter.
In the 2nd scenario, when using the server-side flow, asking the user again (maybe with a reduced set of permissions) is the only way to go – unless you have already gotten an access token before. That will not get invalidated – but it will obviously only contain permissions already given before.
(If the user connected to your app before, you can just call the Auth dialog with no scope parameter at all – in that case Facebook will redirect straight back to your app with a code parameter. Or you could get the token beforehand client-side, for example by calling FB.getLoginStatus.)
As a proof of concept for a simple background application, I used the Graph API Explorer to create an access token for my app to post something to the wall of a page I maintain. It worked fine. Naturally, however, the token expires.
So now I'm trying to have the background application automatically request a new page access token each time it runs. And I'm having a lot of trouble finding a concrete definition of how to do that. There's no shortage of information regarding Facebook and Access Tokens, but nothing seems to demonstrate how to have a background application post to a page. (Not post to a user's wall, not display a login dialog to a user since it's a background application, etc.)
I can fetch an access token in code easily enough by reading the response from a web request to this URL:
https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id={MY_APP_ID}&client_secret={MY_APP_SECRET}
Of course, that "access token" doesn't work when trying to post to the page's wall. It says that the user hasn't authorized the application to perform this action. The action I'm performing is pretty simple:
var client = new FacebookClient(GetFacebookAccessToken());
dynamic parameters = new ExpandoObject();
parameters.message = "this is a test";
dynamic result = client.Post("{MY_PAGE_ID}/feed", parameters);
I've read in some places that I'll need to make a second request, using the first access token, to get the page access token. But I can't seem to find examples of how to do that.
Can someone shed some light on this for me?
I have a Facebook page.
I have a Facebook app which serves no other purpose than to provide a means for a local background application to access said page.
I just need that application to be able to authenticate so it can post something to the page.
(And if there's a step I need to perform in the Facebook UI to permanently give the application permission to do this, I think I've performed that step but it would be good to double check somehow.)
Edit: It's been described to me that I need to obtain a long-lived user access token and, using that, obtain a page access token. The theory is that said page access token won't expire. However, what's not clear to me is how one accomplishes this.
I've read the page describing the deprecation of offline_access, as well as the page describing server-side access. However, I'm clearly misunderstanding something. In the former, it references the latter for obtaining the proper token. The latter, however, includes steps for presenting a login to the user, having them accept permissions, and using the response from that login.
Being a background process that runs unattended, presenting any sort of question to a user (which would be me) isn't really an option. I've also been told that I can't do a one-time request from my browser to get an access token because that is, by definition, client-side interaction and not part of the necessary server-side flow. (It seems odd to me that the service would care if a RESTful request comes from a web browser vs. from an application, but I'm not familiar enough with OAuth or the Facebook API to really make that call.)
So, if I can perform some manual steps to get a permanent access token for the app to post to the Facebook page, what are those steps? Conversely, if I can perform some automated steps in the application to acquire access each time it runs, what are those steps?
(Making a few more API calls from the application adds a second or two of running time to an otherwise once-a-day process, so it makes no difference to me which approach to take.)
At first I just went into the Facebook Application settings and re-enabled the deprecated "offline access" permission. Said application settings can be found at a URL like this:
https://developers.facebook.com/apps/{APPLICATION_ID}/advanced
However, since everything keeps referring to that setting as being "deprecated" then I didn't want to use that as a long-term solution. It may get removed entirely, it may be unsafe in certain circumstances, etc. Better to use recommended functionality.
So here's what I was able to piece together from a scavenger hunt through updated documentation, outdated documentation, a sea of outdated internet posts, and PHP code which mostly made assumptions about functionality that aren't true in all cases...
Visit the Graph API Explorer and select your Facebook Application from the drop-down menu. Click "Get Access Token" and select the permissions you want. (For mine I went to the "Extended Permissions" tab and selected "Managed Pages" and "Publish Stream.") You will be prompted (in my browser it was in a new tab) with a familiar screen where the Facebook Application is asking you, the user, to grant it the permissions you just selected. (You've seen this before if you've ever agreed to use a Facebook Application before.)
The value it produces in the Graph API Explorer (a long string of random-ish characters) is your "Short Lived User Access Token."
As described here in "Scenario 4: Client-side OAuth and Extending Access_Token Expiration Time through New Endpoint" access this URL in your web browser:
https://graph.facebook.com/oauth/access_token?
client_id={APPLICATION_ID}
&client_secret={APPLICATION_SECRET}
&grant_type=fb_exchange_token
&fb_exchange_token={SHORT_LIVED_USER_ACCESS_TOKEN}
(You can obtain the {APPLICATION_SECRET} value on the basic settings page for your Facebook Application: https://developers.facebook.com/apps/{APPLICATION_ID}/summary)
This will return another Access Token as such:
access_token={LONG_LIVED_USER_ACCESS_TOKEN}&expires=5184000
This access_token value (another long string of random-ish characters) is your "Long Lived User Access Token." The expires value is in seconds, which translates into 60 days.
Now we hop over to the Page API reference and take a look at the section on Page Access Tokens. This, along with the basic structure of Graph API requests exemplified here (scroll down to the part where it shows a bulleted list of sample links which include access_token specifiers, which you'll need to specify here because you're requesting non-public information) leads you to request this in your browser:
https://graph.facebook.com/{FACEBOOK_USER_ID}/accounts?
access_token={LONG_LIVED_USER_ACCESS_TOKEN}
This will return a JavaScript object containing lots of useful information about the Facebook Pages and Facebook Applications your user account controls. In my case the Page and the Application had the same name, but it's easy to tell them apart from the category values or, if all else fails, the id values. Find the Page that the background application running on your machine will need to access and copy its access_token (the third and final long string of random-ish characters). The whole node looks something like this:
{
"name": "Some Facebook Application Name",
"access_token": "{LONG_LIVED_PAGE_ACCESS_TOKEN}",
"category": "Musician/band",
"id": "{APPLICATION_ID}",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
}
This is your "Long Lived Page Access Token." This is the value you use to initialize the FacebookClient object in the code. Then, posting a simple status update is as easy as:
var client = new FacebookClient("{LONG_LIVED_PAGE_ACCESS_TOKEN}");
dynamic parameters = new ExpandoObject();
parameters.message = "This is a my status update.";
dynamic result = client.Post("{FACEBOOK_PAGE_ID}/feed", parameters);
Supposedly this "Long Lived Page Access Token" does not expire after 60 days like the "Long Lived User Access Token" does. I'll find out in 59 days, I guess.
NB: The curly braces in my examples are part of the placeholder for actual values. Do not use the curly braces in the actual requests. So something like this:
https://developers.facebook.com/apps/{APPLICATION_ID}/advanced
becomes something like this, for example:
https://developers.facebook.com/apps/123456/advanced
where 123456 is the actual Facebook Application ID.
Being a background process that runs unattended, presenting any sort of question to a user (which would be me) isn't really an option.
As I already said, you only have to do it once.
You get your non-expiring page access token, copy&paste that into your app – and from then on your app can do server-side whatever it wants to do happily everafter.
I've also been told that I can't do a one-time request from my browser to get an access token because that is, by definition, client-side interaction and not part of the necessary server-side flow.
The server-side auth flow for getting a user access token also needs to take part partly in the browser.
It does not matter, if you get a short-lived token via the client-side auth flow and extend it afterwards, or if you get a long-lived one using the server-side auth flow.
(It seems odd to me that the service would care if a RESTful request comes from a web browser vs. from an application […])
Facebook does not want users to give their login credentials to any third party. Therefor, the process of getting a user access token always has to take part in the browser, with the user login in to Facebook.
So, if I can perform some manual steps to get a permanent access token for the app to post to the Facebook page, what are those steps?
Get a long-lived user access token with manage_pages permission. (Or get a short-lived one, and extend it). And then, use that long-lived token to request a page access token for the target page, in the way that is described in the docs.