I want to setup a webhook for facebook leads. i.e Every time there is a lead in facebook I should get a webhook on the configured URL. I am able to do this with the help of the documentation https://developers.facebook.com/docs/graph-api/webhooks/getting-started/webhooks-for-leadgen
However there is no mention of configuring authentication in the documentation. All the endpoints on my system are configured with Oauth2(client credentials grant type) authentication. How do I configure this on facebook webhook setup ?
I was hoping that facebook would have a way to configure authUrl, clientId and clientSecret along with the webhook url, but that is not the case.
Am I missing something here or is it not possible to do so?
Related
Background
I'm trying to implement social login using GitHub accounts and OpenID Connect, but I can't figure out what GitHub endpoints I'm supposed to:
redirect the user to and
POST the authorization code to
...to get back an ID token, or if I already have the right endpoints but the wrong parameters.
I've been following/adapting this guide to implementing social login with OpenID Connect (which uses Google as the Identity Provider rather than GitHub) and referring to the "OAuth 2.0 web application flow" GitHub docs page to try to understand how I need to adapt the guide to work with GitHub (i.e. what GitHub endpoints and parameters I need to use).
My problem
When I POST the authorization code to https://github.com/login/oauth/access_token (the URL specified in GitHub's docs) I get back an access token and a refresh token but no ID token. I suspect this is because the GitHub docs page is meant to be used to implement a plain (non-OpenID Connect) OAuth 2.0 flow.
What I've tried
I did a lot of Googling and found these 2019 slides from PragmaticWebSecurity.com that say I need to initially redirect the user to a different endpoint (https://github.com/openid-connect/auth rather than https://github.com/login/oauth/authorize, see slide 29), but when I try to do that, I get a 404 error from GitHub. I tried emailing the guy who created those slides to ask if the endpoint had changed, but he hasn't responded to me.
These are my guesses at what the answer to my question is:
GitHub doesn't support OpenID Connect / it isn't possible to get back an ID token; I need to just use the access token to query the API to get back whatever information I need about the user.
This would explain why I can't find any mention of social login with OpenID Connect in GitHub's docs.
I have the right endpoint (https://github.com/login/oauth/access_token), but I'm missing some required parameter to get back an ID token.
I have the wrong endpoint.
I contacted GitHub Support and got an official response: Their API doesn't support OpenID Connect for social login.
Here's their full response:
Hi Nathan,
Thanks for reaching out!
GitHub OAuth flow does not currently support the OpenID connect
functionality. You'll need to use the OAuth 2.0
https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps
Regards,
Oluwaseun GitHub Support
So, until they add support for OpenID Connect, you can refer to this write-up I did on how to implement social login using OAuth 2.0:
How do I implement social login with GitHub accounts?
From your guesses 1) and 2).
github oauth apps currently do oauth2 not oidc, it kind of stares in your face with the name, but I missed it as well.
I'll leave this for others researching this.
oauth2 != oidc, Depending on your use case you might have a client library that supports both, the config will look the same, but the response is different and needs to be handled correctly.
As per OpenID specification, I think you'll need to authenticate with OAuth2
The primary extension that OpenID Connect makes to OAuth 2.0 to enable
End-Users to be Authenticated is the ID Token data structure. The ID
Token is a security token that contains Claims about the
Authentication of an End-User by an Authorization Server when using a
Client, and potentially other requested Claims.
...
The OpenID Connect protocol, in abstract, follows the following steps.
The RP (Client) sends a request to the OpenID Provider (OP).
The OP authenticates the End-User and obtains authorization.
The OP responds with an ID Token and usually an Access Token.
The RP can send a request with the Access Token to the UserInfo Endpoint.
The UserInfo Endpoint returns Claims about the End-User.
Then you should be able to forward through OpenID the token, once you have set up the trust between the Authentication provider and the Autorization provider.
Facebook recently released a step-by-step documentation for using a GrapAPI to manage Instagram messages. To obtain the access token to use it, it's necessary to create an application in the developer center, enable login via Facebook and include the permissions "instagram_basic", "instagram_manage_messages" and "pages_manage_metadata" but to activate these options it's necessary to submit various information for approval as statement of how the integration works and descriptions of the usage flow. I don't have access to this information because I can't develop an integration without it being approved.
It's not possible to use the provided test user as the pages raised by him cannot be linked to Instagram accounts.
Tutorial followed: https://developers.facebook.com/docs/messenger-platform/instagram/get-started
Someone with some experience with the Facebook API could give me a light on how to obtain the token with access required and proceed the tests?
I have done the tutorial as well, I faced the same problem. To enable instagram_basic, instagram_manage_messages and pages_manage_metadata without app review you need to create a test-app. For test apps all permissions are granted without review.
Instructions on how to create a test-app
Another usefull tipp: If you are wondering why you need to implement facebook login to access the instagram messaging api, the logic is the following: You need to implement login to then use your own implementation to logg in your own account and obtain the page access key that will let you do api calls to the instagram messaging api. This process is obviously overkill and instagram is working on a way of getting that access token through the developer dashboard.
For now to obtain that access token you need:
implement facebook login as a simple html website and console log the response. Be sure to add the required permissions to the data-scope attribute of the facebook login button:
<div
class="fb-login-button"
data-scope="public_profile,email,instagram_basic,instagram_manage_messages,pages_manage_metadata,pages_messaging"
></div>
deploy to a website that has https enabled (logging in from
localhost will only work if you use a tunelling service like ngrok).
Open your website that has facebook login implemented and logg in with your facebook account that is also linked to the target instagram account and also is admin of your test-app.
get the access token from the response to call the other API endpoints.
So i'm building a website that requires the user to be github authenticated in order to create and publish blog posts via the netify cms.
so in github i've added the application.
the homepage is set as:
https://example.netlify.com
in order to reach the admin area of the site to post blogs and such the user must navigate to
https://example.netlify.com/admin/ and authenticate via github.
now the authentication part is working, i am logging into my github account but it loops back to the oauth page but with a weird url:
https://example.netlify.com/admin/?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=5d971eb88a5073cf804e90d5#/collections/blog
I've set my Authorization callback URL to:
https://example.netlify.com/admin/#/collections/blog
which is where the user should log in to, in order to post blogs and articles
so why does it keep looping? i've obviously set up a field incorrectly, i'm assuming that my Authorization callback URL to is incorrect?
Error = redirect_uri_mismatch
error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.
error_uri=https%3A%2F%2Fdeveloper.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch
The main clue in this error message is redirect_uri_mismatch if you take that and google it you will begin to understand the problem. Part of the security with Identity servers is that the Redirct uri, that being the redirect uri that the Identity server returns your authorization to must be registered on the idnetiy server itself. Someone cant just send a request on behalf of your application and get the authorization back on their own site.
So what ever redirect uri you are sending in your application needs to be registered over on Github for the authorization to work. Its currently not.
You can read more about it here Troubleshooting OAuth App access token request errors
I have a REST service that my mobile app uses to authenticate when the users click on the Facebook or Google icons.
The service accepts the user's id from the provider and checks if it exists on the database and then issues the access_token to be used for the other methods.
The problem is that I just thought that it could be pretty easy for someone to intercept the calls and discover which service authenticates and what the user id is and then call it with to get a token.
How can I avoid this?
I think you just need to separate the authentication and authorization functions. You can let Google (Google Sign-In) handle authentication. If you follow the API they will securely authenticate the user and send you the token which you can validate.
Once you know who they are for sure, your site can safely authorize that user approriately. For example, they might be an existing user, need to make an account, be an administrator. You can make those authorizations on your site based on the user authenticated by Google (in my example).
Twitter, Facebook and others do the same. Also see OpenID Connect.
We have a website where the only way to login and authenticate yourself with the site is with Facebook (this was not my choice). The first time you login with Facebook, an account gets automatically created for you.
We now want to create an iPhone application for our site and also a public API for others to use our service.
This question is about how to authenticate with our website from the app/API and is broken into 2 parts:
What is the correct way to handle REST authentication from an API to a website which only uses Facebook OAuth as an authentication method?
I have read and researched a lot about standard methods of authentication for REST API. We can't use such methods as Basic Auth over HTTPS, as there are no credentials for a user as such. Something like this seems to be only for authenticating applications using the API.
Currently, the best way I can think is you hit an /authorize end-point on our API, it redirects to Facebook OAuth, then redirects back to the site and provides a 'token' which the user of the API can use to authenticate subsequent requests.
For an official application that we create, we wouldn't necessarily need to use the public API in the same way. What would be the best way then to talk to our website and authenticate users?
I understand (I think) how to authenticate 3rd-party applications that are using our API, using API (public) keys and secret (private) keys. However, when it comes to authenticating the user who is using the app, I am getting rather confused about how to go about it when the only way we have to authenticate a user is Facebook.
I feel like I'm missing something very obvious, or don't fully understand how public REST APIs should work, so any advice and help would be greatly appreciated.
UPDATE: see below
I've been thinking hard about this question too. It's not entirely clear to me yet but here's the route I am thinking of going. I am creating a REST API an my users only auth with Facebook connect.
On the CLIENT:
Use the Facebook API to login and get an OAUTH2 code.
Exchange this code for an access token.
In every call to my custom API I'll include the Facebook user id and the access token.
On the API (for every method that requires user authentication):
Make a request to the /me Facebook graph using the access token from above.
Verify that the Facebook user id returned matches the user id passed to my API from above.
If the access token has expired additional communication is required.
I have yet to test this. How does it sound?
--- Update: July 27th, 2014 to answer question ---
I only use the above exchange once upon login. Once I determine which user is logging in, I create my own access token, and that token is used from that point going forward. So the new flow looks like this...
On the CLIENT:
Use the Facebook API to login and get an OAUTH2 code.
Exchange this code for an access token.
Request an access token from my API, including the Facebook token as a parameter
On the API
Receive access token request.
Make a request to the /me Facebook graph using the facebook access token
Verify that the Facebook user exists and match to a user in my database
Create my own access token, save it and return it to the client to be used from this point forward
This is my implementation using JWTs (JSON Web Tokens), basically similar to Chris' updated answer. I have used Facebook JS SDK and JWT.
Here's my implementation.
Client: Use Facebook JS SDK to log in and get the access token.
Client: Request JWT from my API by calling /verify-access-token endpoint.
MyAPI: Receives access token, verify it by calling /me endpoint of Facebook API.
MyAPI: If access token is valid, finds the user from database, logs in the user if exist. Create a JWT with required fields as payload, set an expiry, sign with the secret key and send back to the client.
Client: Stores the JWT in local storage.
Client: Sends the token (the JWT from step 5) along with the request for the next API call.
MyAPI: validate the token with the secret key, if token is valid, exchange the token for a new one, send it back to the client along with the API response. (No external API calls for verification of the token here after) [if the token is invalid/expired request client to authenticate again and repeat from 1]
Client Replaces the stored token with the new one and use it for the next API call. Once the token expiry is met, the token expires revoking access to API.
Every token is used once.
Read more answers about security and JWT
How secure is JWT
If you can decode JWT how are they secure?
JSON Web Tokens (JWT) as user identification and authentication tokens
I am trying to answer the same question and have been going through a lot of reading recently...
I won't have "the" answer but things are getting a little clearer for me. Have you read the comments in the article you mentioned? I found them really interesting and helpful.
As a result, and in the light of how things have evolved since the first article has been written, here's what I think I'll do:
HTTPS everywhere — this allows you to forget about HMAC, signing, nonce, ...
Use OAuth2:
When authentication requests come from my own apps/website, use this 'trick' (or a variation of it) described in a reply to the article mentioned before.
In my case, I have two types of users: those with classic login/password credentials and those who have signed up with Facebook Connect.
So I'd provide a regular login form with a "Login with Facebook" button. If the user logs in with his "classic" credentials, I'd just send these to my OAuth2 endpoint with a grant_type=password.
If he chooses to log in via Facebook, I think that would be a two-steps process:
First, use Facebook iOS SDK to open an FBSession
When that's done and the app is given back control, there should be a way to get a Facebook ID for that user. I'd send this ID alone to my OAuth2 endpoint with an extension grant understood by my server as "using an FB User ID".
Please note that I am still heavily researching on all this stuff, so that might not be a perfect answer... maybe not even a correct one! But I think that would make for a good starting point.
The idea of using an "extension grant" for the Facebook authentication might involve having to register it to do things properly? I'm not quite sure.
Anyway, I hope I was able to help you even a bit, and that at least it can start a discussion to find the best solution to this problem :)
Update
The Facebook login is not a solution as pointed in the comments: anybody could send an arbitrary user ID and log in as this user on the API.
What about doing it like this:
Show a login form with a "Facebook login" button
If this login method is chosen, act kinda like the Facebook SDK: open a web page from your authentication server, which will initiate the Facebook login.
Once the user has logged in, Facebook will use your redirect URL to confirm; make that URL point to another endpoint of your authentication server (possibly with an extra parameter indicating the call came from an app?)
When the authentication endpoint is hit, the authentication can securely identify the user, retain its FB User ID/FB Session and return an access token to your app using a custom URL scheme, just like the Facebook SDK would do
Looks better?