Facebook Messenger: get access token of linked account - facebook

First off, I'm not looking for the access token of a facebook account.
I (or my facebook messenger bot) need the access token of a linked 3rd party account.
The account was successfully linked as described here: https://developers.facebook.com/docs/messenger-platform/identity/account-linking
Slightly off topic: The first issue I noticed that does not meet the OIDC/OAuth2 specs is, that the redirect URI given to the /authorize endpoint expects a param "authorization_code" instead of "code" with the actual authorization code. Ok, good thing we do not use off-the-shelf software for the IdP, so I could mend that. Yet.
Now, I'm accustomed from the Amazon Alexa account linking to let the amazon do the token management, refreshing etc. and to deliver an 3rd party access token with every request.
But not with Facebook, it seems. As far as I managed to understand (not by the docs, but by try&error), for the Facebook Messenger the account linking is finished once they get the authorization code (and call an associated webhook).
But since I need an actual access token for every request to my bot, that's not gonna help much.
It now looks as if I have to extend my bot to be a complete, but not standardised, OAauth2/OIDC client (including token handling, refreshing etc.) with some problems:
how to check the validity of the redirect URI?
should be the same as in the initial request
how to validate the authorization_code?
keep in mind, normally this bot has no connections/access to the database of the IdP
how to link this to a specific facebook user id?
My question now is, how to cope with that behaviour when I aim to use standardised software for the OAuth/OIDC IdP? Any ideas?
Thanks in advance
Thomas
EDIT:
To clarify what is meant by "account linking": I'm not interested in the users facebook account, I want to access information of a 3rd party account (provided with my actual service) of that user.
For example a call like "How many pictures are in my tumblr account" will need the customer to link the tumblr account to this facebook messenger bot.
For comparison: this worked extremely smooth with Amazon's Alexa and Google Actions. I simply had to input the client credentials and OAuth endpoints and thats that. If the user successfully linked the 3rd party account, I get an access token with every query to my backend, as expected.
EDIT2: as pointed out by CBroe, this is not supported by Facebook. Only actually "linking" the User IDs is possible.

Related

APIs for a Instagram feed viewer

I wish to implement an Instagram feed reader for my website. A reader that will show my Instagram feed in a unique interactive manner without asking the user to login to Instagram. Is there a way for me to do this reliably using Instagram APIs or their new Instagram Business APIs?
Current options and their caveats:
1. The Instagram v1 API found here (https://www.instagram.com/developer/)
requires user to authenticate. There is no way for an application to use grant_type=client_credentials to acquire a token and make API calls.
The tokens generated don't seem to expire but a note says they may expire any time, making a solution that uses a manually generated token unreliable.
https://www.instagram.com/developer/authentication/
2. Instagram Business accounts API found here (https://developers.facebook.com/docs/instagram-api/)
requires an Instagram business account, and at the same time the queries to media endpoint seem to require User Access Token, which again requires a user to login for generation/renewal of token. (https://developers.facebook.com/docs/instagram-api/reference/media/)
I'm aware of endpoints like https://www.instagram.com/{username}/media/, but this is undocumented and can disappear any moment.
I will highly appreciate any help, or recommendation to implement such a feed that does not require a user to generate authentication tokens.
as it is said in Instagram API doc:
In your application, you should have each user go through an authentication and authorization flow in order to receive a valid access_token.
so I can see just too ways:
use '/media' end-point until it is blocked (i believe it is relatively reliable, because anything can disappear one day, not just undocumented things)
authenticate yourself on instagram, and use your own access_token for API requests, as it is done in several popular tools for getting instagram recent posts

Identity Providers with Xamarin Forms and Azure

I'm a bit confused about Identity Providers in a project I'm doing with Xamarin Forms.
I configured Facebook as an IP with Azure Mobile Apps following this page
https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-how-to-configure-facebook-authentication
It works, but my doubt is, how can I use the MobileServiceUser result of the authentication process to, for example, post to Facebook or get personal information from Facebook. Is this possible?
Thanks!
This is how I think about it.
Identity providers are used to provide a third party guarantee of WHO a user is.
The Mobile SDK lets you do Authorization. So you can decide WHAT the user can do on YOUR service after you know WHO they are.
Any thing you are doing via facebook would still need to be done through the Facebook API/SDK using the token their Authentication process returned to you.
Finally I found the solution to my problem.
What I was trying to do is get information from Facebook after I have authenticated myself.
All I had to do was invoke
await client.InvokeApiAsync("/.auth/me");
After authentication and thats all, the response of that request has the token to access the Facebook API. These tokens are saved in Azure.
For more information:
https://cgillum.tech/2016/03/07/app-service-token-store/
Thanks!

Using Facebook or Google login API with Classic ASP

I'm running a Classic ASP website, that has its own user authentication and login mechanism. For example, In order to remember a logged-in user, ASP creates an encrypted cookie and a 20-minute session for each connected user. If the 20 minute session is elapsed, the server revives the session from the cookie saved previously, and saves some data regarding the user to the database.
I want to to be able to allow users to connect with their Facebook or Google identity, but the mechanism used by Facebook or Google is based mainly on Javascript and on client-side code.
How Facebook or Google login can be used while maintaining server side code in ASP? (So that the ASP server can still manage the session and save data regarding it, for example whenever a session is revived)
For me somehow it seems that it may become less secure to use client-side authentication as the code may be altered easily. Isn't this the case?
If I use client-side javascript and log in with Facebook, how would I update the user data retrieved from facebook back into my database, for example the user's first and last name?
For me it sounds that it should be a "server-to-server" communication (between my ASP server and Facebook's or Google's servers) and what they propose is a "client-to-server" communication ... Any ideas how this can be done?
Any help or explanation would be very much appreciated! Thanks.
I'll try to address your Facebook-related questions one by one. However, I will not give you an implementation or any ASP-specific feedback, but only a rough approach. Additionally, I recommend that you study Facebook's documentation on Facebook Login extensively to further your understanding of the matter.
1. Facebook documents the server-side OAuth 2.0 flow in their Manually Build a Login Flow guide. Basically you redirect the user to a specific FB URL that (in the parameters) tells FB to render the "Login with Facebook" dialog, and which permission scopes to ask for. Once the user approves the Facebook Login for your webapp, they will be redirected back to your web app, e.g. with an OAuth token in the query string, that your webserver can then exchange for a user access token.
Once you obtained a user access token, you could e.g. store it in your web app user's session.
2. I don't know what you mean. Client side apps are fairly secure. Perhaps you can convince yourself about how secure JS apps are when reading about things like CORS.
3. If you only use JavaScript (e.g. Facebook's JS SDK) and you want to store e.g. app-scoped user IDs on your server, you need to expose an endpoint on your server that your JS application can submit that kind of information to.
4. You state
what they propose is a "client-to-server" communication
Who are "they", and where are the proposing this? The resources I linked to in 1. should explain how you can use Facebook login in a pure server-to-server way.

Can I safely authenticate a Facebook user with just Facebook Signed Request?

I want to enable my users to associate their user account with a Facebook or Twitter and allow them to login on my server with their Facebook/Twitter account instead of using the classic username/password. Basically the same idea as the login in StackOverflow.
My current approach for Facebook:
The client application will perform OAuth and then use their Facebook id to login on my server. Based on this Facebook id, the server will lookup the associated user account and perform login without asking for username/pasword. However just relying on the Facebook id to login is not very safe, as that is the same as using only a username to login instead of username & password.
So to make sure the Facebook id is authentic, the client application will also provide a FBSR (Facebook Signed Request, see: https://developers.facebook.com/docs/facebook-login/using-login-with-games/#checklogin) with the login request.
The server will check two things with this FBSR:
The Facebook id in the request must be the same as the one hidden in the FBSR
Server will recalculate the signature part via the Facebook secret key. This must match with the signature in the FBSR .
Normally the server should perform a check with the Facebook server with the oauth_token to be 100% sure of the users identity. However I need skip this in order to avoid dependency to Facebook server on our server.
I have 2 questions:
1) Is this above approach good enough? Can it be improved (without server-to-server communication)?
2) I want to do the same with a Twitter account, but the their signed request is different then Facebook. It seems the Twitter user id is embedded in the oauth_token, so my approach may work with a little tweak, but I am not sure whether the user id is always part of the oauth_token and cannot get this confirmed after searching the internet.
I think that your approach is good enough and don't see any way to avoid server-to-server communication with a signed request. Bear in mind that, with Facebook Graph Api Version 2, in order to protect the privacy of the user, Facebook will send out not the real user id, but one generated for apps. It will also be possible to enable anonymous login.
I am not sure of what you're trying to do with Twitter, and why you compare the APIs (they're quite different). The Twitter login, also know as Sign in with Twitter, used for any website or mobile app, should work for you too.

Long-lasting FB access-token for server to pull FB page info

I'm aware that there are many questions about Facebook access-tokens and the grief they cause, but despite much experimentation and reading many frustratingly vague blog articles (FB and otherwise), I'm still struggling to get a clear answer to my needs. Let me succinctly break down my process so far:
I am creating a site that, server-side, needs to pull the posts/statuses from a single Facebook Page
I am an admin of that Facebook Page
I have created a Facebook App
Using the Facebook Graph API Explorer, I've generated a short-lived key, connected to my app and my account, that grants permission to my account to view the access-tokens for my pages
I've converted my short-lived key to a long-lived key (60 days) ala scenario 4 from this
And here's where I am stuck. My 60 day key works fine for my server to pull the info needed from the page, but as far I can tell, there's no way to programmatically extend that 60 day key. I also do not know of a way to generate a new short-lived key without manually going to the Facebook Graph API Explorer and creating one.
Since it is my server making the requests to the Facebook API and not a user-based system (where I could easily request that a user authorize the Facebook app again), this creates a very clunky system. Since Facebook deprecated offline_access, is there really no permanent way to have my server pull info from my own page? Will I really have to create a new key by hand and manually update my server with it every 60 days?
Or is there something I'm missing?
Update:
The step-by-step guide that was previously found here has been migrated down into its own answer.
These are the steps that were previously in the question - they have been migrated to this answer.
Having found that it is possible to generate a Facebook Page Access Token that does not expire (with help from #Igy), here is a clear, step-by-step quide for all those looking to the same:
Make sure you are the admin of the FB page you wish to pull info from
Create a FB App (should be with the same user account that is the page admin)
Head over to the Facebook Graph API Explorer
On the top right, select the FB App you created from the "Application" drop down list
Click "Get Access Token"
Make sure you add the manage_pages permission
Convert this short-lived access token into a long-lived one by making this Graph API call:
https://graph.facebook.com/oauth/access_token?client_id=<your FB App ID >&client_secret=<your FB App secret>&grant_type=fb_exchange_token&fb_exchange_token=<your short-lived access token>
Grab the new long-lived access token returned back
Make a Graph API call to see your accounts using the new long-lived access token: https://graph.facebook.com/me/accounts?access_token=<your long-lived access token>
Grab the access_token for the page you'll be pulling info from
Lint the token to see that it is set to Expires: Never!
That should do it. You should now have a Facebook Page Access Token that doesn't expire, unless:
You change your Facebook account password
You lose admin access for the target page
You delete or de-authorize your Facebook App
Any of these will cause the access token to become invalid.
If you are getting (#100) Tried accessing nonexisting field (accounts) on node type (Page), go to the Access Token Debugger, copy the value of User ID, and use it to replace the "me" part of the URL in step 9.
This is covered in the Offline Access deprecation document
Use the 60-day token for the page admin to retrieve a Page Access Token (via /PAGE_ID?fields=access_token or /me/accounts) - the Page access token will not have an expiry time
An approach that works in 2019
I was recently trying to achieve something similar (to the use case described in this thread), but I wanted to make sure to respect Facebook's current policies, so I did a little research and here I'm sharing what I found.
My use case
So, as I said already, my use case is very similar to the one described here; that is:
I'm doing some work for a school district.
They are using a software tool to manage pretty much everything that relates to school transportation.
That tool allows them to send email notifications (to subscribers) when they publish bus delay alerts and school closure alerts.
A lot of people in the community follow the organization on their Facebook page, and that's the only place they look for those alerts.
So an employee of the organization has to manually publish each notification on the Facebook page (in addition to creating it in the transportation software). Moreover, those notifications eventually expire (or are simply deleted before they expire), so the employee has to go back later on to delete them manually as well.
It's a waist of time, so what we are trying to do here is to develop as simple system that periodically polls the software tool's database for new (and expired) notifications and update them (i.e. add and remove) on the Facebook page.
This is, in my view, a legitimate use case, but I wasn't sure how to implement it in a way that's in line with Facebook's policies.
The accepted answer
I followed the steps of the accepted answer and it worked, except that things appear to have changed: now, even though the generated page token does not expire, access to data does expire after around 60 days. You will see that as well if you follow the procedure and inspect the page token in the FB Token Debugger Tool.
Besides, the fact that the generated page tokens are tied to the user account is also unfortunate, because if the user updates his/her password, then the page token also gets invalidated.
How to do it in 2019
After several hours of research, I stumbled upon the following Facebook documentation article: Business Login for Direct Businesses.
It turns out that it is now possible, following the steps described in the above article, to generate a page token that is not associated to any particular Facebook user account and which will not expire (unless the FB App gets deleted or the underlying application token gets deleted, you know...)
So here are the steps and the most important parts:
You need a Business Manager account.
Verification will be required and a digital contract will have to be signed.
You need to add the target Facebook page to that account.
You need to create a Facebook App, and transfer that app to the same Business Manager account as well.
The app will have to go through Facebook's review process, because the following permissions will be needed: manage_pages and publish_pages.
Important note For the posts made using the generate page token to be visible to users other than the application administrators, that app will need to have been published and approved.
You may still experiment with the concept without submitting for review, but the posts won't be publicly visible.
In the Business Manager account (only after your app and page have been added to the account), you need to create what's called a System User, and give that user admin role (or permissions) to the target Facebook page.
A system user is owned by the Business Manager account, and isn't tied to a specific user. My current understanding is that one major use case for a system user is programmatic access to Facebook's Graph API (just what we need).
Then, for that system user, you need to generate a access token (which will be never-expiring). You will be prompted to select for which app. You will then select your target app.
You will then need to use the generated app token to generate a page token, which will also be never-expiring. The procedure is described in this article as:
GET /<PAGE_ID>?fields=access_token&access_token=<SYSTEM_USER_ACCESS_TOKEN>
That's it.
That token will never expire, and it won't be tied to a particular Facebook user, so it's exactly what we need!
The last part is to make sure that your Facebook app gets approved by Facebook. It's in fact the most important part, because the whole procedure is worthless if people don't see our posts.
I wanted to know for sure that I could rely on the above procedure to build something for my client without Facebook rejecting it in the end, so, beforehand (i.e. before starting to work on my client's project), I went through the whole process of creating a page, an app, a Business Manager account, etc. I verified my business. I submitted my app for review. In my request, I was very specific about my use case and emphasized that the app was for "self-use" (i.e. that the organization is developing an app for itself, not for other Facebook users). I got approved without less than 24 hours.
A few other notes about the app review process:
I had to select a platform for the app, so I selected website.
I had to indicate why the app needed the two permissions and how it was going to use them.
I had to indicate why the reviewer would not be able to sign into my app and try it (i.e. because the app will be used by a worker process).
For the mandatory screencasts, I simply presented manual operations in the terminal using the curl utility (to generate the page token and make posts to the Facebook page). I also showed how I was using Business Manager to link the system user to the page and generate a token, and so on.
Again, I was very specific about my use case, and I think that that helped.
I hope this information will be useful to people with similar use cases.
Many thanks to #redhotvengeance for step-by-step guide.
After some time, now there is clearly described in Facebook documentation:
https://developers.facebook.com/docs/facebook-login/access-tokens/expiration-and-extension
Extending Page Access Tokens
Apps can retrieve a page access token from Page admin users when they
authenticate with the manage_pages permission. If the user access
token used to retrieve this page access token is short-lived, the page
access token will also be short-lived.
To get a longer-lived page access token, exchange the User access
token for a long-lived one, as above, and then request the Page access
token. The resulting page access token will not have any expiry time.
You can also copy and past from the app dashboard on facebook.
The steps:
Go to https://developers.facebook.com
Select your app in the top right corner of the page
(pic of what it looks like)
Click on Messenger from the options on the left (it will go to setting automatically) (pic of what it looks like)
Go to the "Token Generation" section in the page. Select what page you want to generate the token for. (pic of what that section looks like)
The copy and past your page token where ever you need it.
Keep in mind that while in theory your token won't expire, that it is directly tied to what ever facebook account your logged into. So say you change your password or you remove the permissions from between your account and your app then your token won't be valid any more.