Graph API doesnt return Profile's picture - facebook

I read this documentation, and it says that for retrieve picture I need to use an access token. So, I've use it using publish_actions and email as scopre/permission, but I don't see any `picture" returned on the JSON:
https://graph.facebook.com/myNickname/?access_token=myAccessToken
the rest of data is returned, the ones where access_token is required not. I should use User Access Token, not App Access Token.
The same happens for the others field, such as age_range. It is not returned.

You can see in the doc for age_range that the field will be retrieved only if you specify it in your request:
The user's age range; only returned if specifically requested via the fields URL parameter
The same happens to picture property. The problem is, that they didn't mention it in the documentation.
To get picture, specify in your request:
/me?fields=picture

Related

Cannot generate access token in Exact Online API using POSTMAN

I have followed the Exact Online documentation to generate access token using authorization code using POST method as written in official documentation.
Documentation link: Get access token documentation
But for some reason, the response to this request is invalid and cannot generate access token. What could be the possible solutions?
Expected Outcome as per documentation:
{ code: "XTzM!IAAAACbPTzQJXwFhM"
, redirect_uri: ...
, grant_type: "authorization_code"
, client_id: "b81cc4de-d192-400e-bcb4-09254394c52a"
, client_secret: "n3G7KAhcv8OH"
}
Use the GET method instead of POST.
If that’s not working try to past the url with all the details present in the address bar of a browser. A form will be presented to you and fill in your username and password. After that take a careful look at the address bar. There you will find the token.
Btw why not use the implicit flow (use ‘token’ for grant_type). Access token is returned immediately.

Retrieve email from token | #auth0/auth0-spa-js

I have been trying to upgrade to #auth0/auth0-spa-js from auth0-js, although I could not get my head around reading an email from a token which in turn was obtained from await useAuth0().getTokenSilently()
I use jwt.io to decrypt the token, and this is what I get in the payload:
{
"iss": "https://TENANT_NAME.auth0.com/",
"sub": "auth0|SOME_HASH",
"aud": [
"https://API_IDENTIFIER",
"https://TENANT_NAME.auth0.com/userinfo"
],
"iat": 1563699940,
"exp": 1563786340,
"azp": "SOME_OTHER_HASH",
"scope": "openid profile email"
}
When I was using auth0-js I could just add scope: "openid email" to new auth0.WebAuth({...}) and voilà – I had email and email_verified in the payload of the decrypted token.
I believe the 2 part series of tutorials were not able to answer my question, and retrieving the token from a hooked getTokenSilently() inside my Apollo configuration was also a challenge on its own. I like the redirect implementation for SPA, however. Please, can you suggest a proper way to include email and email_verified in the token's payload?
UPDATE
By reading this piece of documentation on api-tokens I understood the token I am getting from getTokenSilently() is called the access token. I have been using ID tokens in all of my requests' headers till this day, and that was probably a bad approach:
In the OIDC-conformant pipeline, ID Tokens should never be used as API tokens.
Also, the documentation says:
The token does not contain any information about the user except for the user ID (located in the sub claim).
In many cases, you may find it useful to retrieve additional user information. You can do this by calling the /userinfo API endpoint with the Access Token.
Which I did by following the shell example. I have sent the request with my access token and magically got an object containing the user's profile information from Auth0's Custom API.
We got close, what is an algorithm converting the "sub" into user profile residing inside Auth0's Custom API which I can implement for my backend written in ruby?
Yes, as you mention, ID tokens should not be used as API Tokens. They have a different usage (and you don't want your API Token to be too big, because you send it in each request's headers).
To get the user email, you can just fetch the UserProfile given in the ID Token. To achieve that, you just have to call getUser instead of getTokenSilently.
If you want more infos about the user, you have 2 ways to fetch user info:
You use the Auth0 Management API to fetch the user infos, based on the user id (in the sub claim of the ID Token) and using this API endpoint. In Ruby, you can just use a basic HTTP request.
You use a rule to always include specific fields in the ID Token. For example, you can include user_metadata and app_metadata in your ID Tokens. That way, you can use it without additional API call. To achieve that, you will need a specific Rule that will run when ID Tokens are generated (more general API doc).
An example rule that would add all user_metadata and app_metadata to the ID token would be:
function (user, context, callback) {
const namespace = 'your_url_namespace_just_for_cosmetic_but_required/';
context.idToken[namespace + 'user_metadata'] = user.user_metadata;
context.idToken[namespace + 'app_metadata'] = user.app_metadata;
callback(null, user, context);
}
And you will have the info in your ID Token for your frontend to use.
For the record, more rules examples on this hard-to-find page.

Even though Facebook API returns 'code' 200 for some 'nodes', when accessing the webpage it return 404

I'm developing a web app that uses FB data for some FB posts. I have a bunch of post ids and am fetching the data related to them using batched requests. Then am showing a summary of each post (number of comments, shares, likes) and link to the actual FB page (https://www.facebook.com/). But clicking on the link shows a 404 page on FB!!
Example, the node_id, '69983322463_10152179775342464' will return data in the graph explorer. But when you access https://www.facebook.com/69983322463_10152179775342464 it returns 404!
In case my question is not clear:
GET https://graph.facebook.com/69983322463_10152179775342464?access_token={a valid access token} returns data.
But GET https://www.facebook.com/69983322463_10152179775342464 (with or without an access_token param) returns a 404
Is there some field in the API response that signifies that the page does not exist anymore?
Thanks,
mano
This is because not every post is public. Only publicly available posts can be accessed directly.
For rest you need a valid access token to GET its details. When you tried the post id in graph api explorer it showed the result since an access token was applied.
So, you simply use a valid access token, may be any app access token (app_id|app_secret)- that never expires, and make the /GET request.
Eg: \GET /69983322463_10152179775342464?access_token={app-access-token}

Facebook server-side authentication flow: is this the right "code?"

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.

Facebook canvas url with params?

I have a website in which i use the Facebook API to let users 'invite' their friends to my site. These friends will get an App invite on their Facebook and once they click and accept it, it opens a page of my site in side an iFrame (within Facebook).
That's all fine, but i would like to add a refer id to the URL. So i can tell from who they got the invitation.
Is it possible to add (dynamic) parameters to the canvas URL??
I haven't been able to find out how to do this.
(I'm using the JS library).
I am able to pass multiple params to my canvas page. Not quite sure why this is not working for you or for #JonCanning. I am able to successfully redirect to https://apps.facebook.com/MY-APP?param1=x&param2=y&param3=z and retrieve them within the code loaded in the iframe.
You cannot manipulate request urls if you use apprequests for invites though, so not sure how you plan to manipulate the request url. Is this a wall post mechanism?
But, if you are using apprequests for invites - you can pass an optional "data" param. This can be arbitrary JSON or a simple string. When a recipient clicks thru the invite, you will be provided a "request_id" param in the request redirector from Facebook. e.g. http:YOUR-INVITE-REDIRECT-URL?request_ids=REQUEST_ID. If multiple invites from the same app were sent to the user, you will get the request_ids as a comma separated list. You can make a call back to the facebook graph api endpoint for requests and get back all the info for the requests - including the "data" param you passed. This might work better for you since you have embedded all data in the request itself.
More info on dialogs here : https://developers.facebook.com/docs/reference/dialogs/requests/
A single parameter passed into your apps url is passed onto the iframe
http://apps.facebook.com/app_name/?param=hello
To add to #iyerrag's answer, to grab the data param from within your canvas handler, you have to call back into the facebook graph API. The call takes one of the request_ids passed in the http query and also an access token. I was able to use our app's access token (generated something like this Creating App Token).
The returned JSON document contains the value you passed in the data param in key 'data'.
Here's the gist, in Python:
requestIDStr = self.request.get('request_ids','')
requestIDs = requestIDStr.split(',')
requestID = requestIDs[0]
if requestID:
url = """https://graph.facebook.com/{}?access_token={}""".format(requestID, fbAccessToken)
try:
response = urllib2.urlopen(url)
responseDoc = response.read()
jsonResponse = json.loads(responseDoc)
dataParam = jsonResponse['data']
except Exception as e: logging.warning('unable to retrieve data param: {}'.format(e) )