Facebook GraphQL - How to get a users email address and name from backend - facebook

I have an app where the user logs into Facebook (and thus has an Auth Token) and then sends that token to my server for authentication within the app.
If it's the users first time in the app, I need to sign them up as well (gather email and name)
Using the users FB auth token (and any server-side tokens) how do I retrieve the user's email address and name? (What endpoints do I need to hit with what tokens/body?)
--
Additional Info:
The login is scoped with ['public_profile', 'email']
The application is running in Node.js on AWS Lambda, and I'd prefer to make a simple fetch if possible instead of installing a whole gql client.
I have tried looking at their graphQL documentation, but I can't
seem to make heads or tails out of it.
I do have access to the user's ID (example: 10157426730xxxxxx)

This would be the API call to get the name and email of a user, with a User Token:
https://graph.facebook.com/me?fields=name,email&access_token=xxxx
Alternatively, you can add the version:
https://graph.facebook.com/v4.0/me?fields=name,email&access_token=xxxx
All the existing fields for users are here to find: https://developers.facebook.com/docs/graph-api/reference/user/
You do not need the User ID, the User Token identifies the User anyway and you can just use "me" instead of the ID. The Graph API is a REST API though, not GraphQL.

Related

Facebook OAuth security using passport-facebook

I am currently using a client-side React component to have a user login to Facebook via OAuth in my application. On the server-side, I use the npm package passport-facebook-token to validate the authenticity of the accessToken after a successful client-side login.
One practice I do not see often is in addition to asking Facebook if the accessToken is valid, shouldn't the server also check if the email provided by the client's payload matches the e-mail coming back from Facebook? Allow me to use defined client/server technologies to illustrate my question:
1) User uses React component on the client to authenticate with Facebook.
2) React component successfully authenticates with Facebook and fires an HTTP request to the server with an access token and the user's email.
3) The server, running Node.JS and passport-facebook, now needs to verify the authenticity of the access token directly from Facebook. Facebook does not care for an e-mail. It will just verify the access token.
4) Facebook returns a response to Node.js confirming the authenticity of the access token. The response also contains other metadata about the user, including their email and other profile data.
My question is, should Node.js take the email that's also coming back from Facebook's access token verification payload, and verify that it is what came back from the React client? Would this not prevent someone from brute-forcing an accessToken and require them to not only have an accessToken but also know who the accessToken belongs to? This could prevent a user from submitting a bunch of HTTP POST requests to the Node.js server attempting different access tokens. They would not only have to guess an access token assigned to the application's clientID, but also know the e-mail it belongs to. Is this an over-engineered approach?
Really the best way I can think of to make your OAuth accessToken and 'code' value less prone to brute-forcing is using a Cryptographic Number Generator to create a 128-bit length string of random data and encoding it with base 64 to use as your code. It's extremely unlikely that it would be guessed by a computer or by someone redirecting to and from the authorization endpoint and the redirect-uri with query parameters.
Another method of fortification is limiting the rate of authorizations by IP address (which you can do instead of email through Node.js) but that is usually not a problem for most well-equipped hackers. I highly advise the first method for creating a more secure service.
Your approach to validate the email as well as the token is a bit superfluous because Facebook's opaque user access tokens are inherently tied to email.
From Facebook
An access token is an opaque string that identifies a user, app, or Page
"opaque" is defined by Auth0 here
Opaque Access Tokens are tokens in a proprietary format that typically contain some identifier to information in a server’s persistent storage
In your case, the identifier is the user's email, and the server belongs to Facebook.
I will elaborate further. Here is your step by step with some edits:
User uses React component on the client to authenticate with Facebook, inputting both their email and password directly to Facebook. React component gets the token from Facebook on login success.
React component successfully authenticates with Facebook and fires an HTTP request to the server with an access token and the user's email.
The server, running Node.JS and passport-facebook, now needs to verify the authenticity of the access token directly from Facebook. Facebook does not care for an e-mail. It will just verify the access token because the access token is already tied to the email.
Facebook returns a response to Node.js confirming the authenticity of the access token. The response also contains other metadata about the user, including their email and other profile data.
This is Facebook's bug bounty program. If their OAuth was really as cracked as to require a second email validation, it would have been patched almost immediately by this incentive.

How to get impersonated UserGuid Id in docusign

I am trying to get the impersonated userguid from the docusign api. Per the documentation I need to call /restapi/v2/accounts/account_id/users?email=email, which is not working for me. I assume the full url would be https://admin.docusign.com/restapi/v2/accounts/account_id/users?email="sampleemail#gmail.com" .
I am getting a 404 when entering my email in the above format.
Looks like you have the incorrect domain. API Calls generally don't get made against admin.docusign.com. You'll want to make that call against the Application Server your account is on.
In the Sandbox environment that will be demo.docusign.net. In prod you'd need to make a UserInfo call to determine which server your account is on. It could be something like www.docusign.net or na2.docusign.net, but there are several possible domains.
In order to get Impersonate GUID ,
Login to admin account
Under setting options Click API and keys
Value under the user id text box is Impersonate GUID
During configuration & setup:
1. You have an account admin enter information such as account, their userId ("API User Name" in web app). Save both items.
2. You follow the "consent flow", get their consent, generate a JWT and
exchange for a token.
3. Use the /user_info call against the account
server to get the list of their accounts. If more than one account
in the array, find the one that matches what they entered in the
configuration. Get and save the associated "base_uri". You will
use that for all subsequent API calls.
Your application now has stored the account ID, the admin's "userId", and the base URI to built API URLs.
During business application operations:
Admin is "Bob". Sender is "Jill"
You need to get an access token for Jill.
1. Create JWT for Bob, exchange for access token, make GET /users?email={Jill's email). This gives you Jill's "userId".
2. Create JWT for Jill, exchange for access token.
3. Make API call as Jill, using her access token.

Separate APIs for User Login?

I need to create an API for login for my website.
There can be 3 ways for a user to login:
via Username/Password combination
via Google+ Token and EmailId
via FB Token and EMailId
Should there be a single API for this or should all the above exist as separate APIs? The output for the Login API will always be a token that will be used to make further authenticated requests.
I think it's more a matter of taste. I'd have a generic ProviderAuthentication API endpoint that receives a token id and another Authentication API endpoint that receives username & password. But you can also aim towards REST level 1 and have some generic Login resource (that contains username, password, providerToken & token properties) to work with a generic Login API endpoint.

How to contact Facebook application users without token

My Facebook application has a few thousand users but they have not visited the application for a long time and I don't have access tokens for them. I do have their uid's.
How could I make contact to my application users?
I used to use the Notification.sendEmail but it is now deprecated and won't send any emails. I have email permission for all of the users but I didn't store the users email address earlier because I used that function. I should have stored the addresses.
I have understood that all use of new Graph api require access token. So my option would be to use the old Rest api. But is there a method that could be used in a situation like this?
You should be able to still retrieve the email addresses of the users who granted your app the email Permission if they haven't subsequently removed it - you can do this with the App Access Token (see the Authentication docs for more info)
Make a call to /<USER ID>?fields=email to get the address

Retrieve email using Graph API

I am using app login access token retrieved through following API -
https://graph.facebook.com/oauth/access_token?client_id=&client_secret=&grant_type=client_credentials
Can I retrieve email address (primary email not the facebook email) of any user if it is public using Graph API?
Thanks
Lakhan
Two ways to get users primary email:
For the authenticating user (ie the one who has granted your application access to their profile) and only when you explicitly request that permission.
If the email is explicitly made public by some arbitrary user not authenticating with your app, then that will be available to you also. Any publically visable info you can see via facebook.com is equally accessible via the API.
For getting the authenticating users email, when you first request the oAuth dialog you need to pass a scope with the email permission (as well as whatever other permissions you require). See more about permissions here and more about using scope here .
When the email is available it can be found in the User payload, see more about the API request and payload here.
Check the doc here : http://developers.facebook.com/docs/reference/api/user/
With the email argument, you will be able to get the email.