How to verify email and name on a server using FB access token received by javascript SDK on a client side - facebook

I have a client (HTML+JavaScript) and a server (ASP MVC) and I need to provide a user some private information. To achieve that I need to verify that
user authenticated and
use users email address to retrieve its
private information.
I want to use FB authentication. It looks pretty straight forward but has a flaw which I am sure people can tell me how to solve or what am I missing.
client initializes FB SDK and requests user to authenticate using FB
result of successful step #1 is access token.
We can place another call to FB using this access token to retrieve
email and name.
How can my server know what is the email and name of the authenticated user?
My understanding that client should not send email and name to the server (it can be hacked and can not be trusted) but instead client should send the received access token, which server should use to get user's email and name, but on the server side.
Please explain, give me an example, point me to a link on how can I achieve that on the server as all my searches for that failed.
One more time, my backend is ASP MVC.

On the server, make a call to the Graph API:
https://graph.facebook.com/me?fields=name,email
Use the Access Token and you will get the correct data:
https://graph.facebook.com/me?fields=name,email&access_token=xxx
Btw, you should also read this: https://developers.facebook.com/docs/graph-api/securing-requests

I guess I was confused with what I need to do in ASP MVC in order to get a user info having an access token.
The suggested link: https://developers.facebook.com/docs/graph-api/using-graph-api helped me to understand that all I really need is to make a HTTPS GET call (from the server) to "graph.facebook.com" passing access cookie (received from the client) to retrieve the information I need and exclude a possibility of hijacked/compromised client passing me a wrong email.
Using GRAPH API means placing https calls to GRAPH.facebook.com - that was no clear to me.

Related

Authentication Practices with Node Express

I built a simple authentication system for my backend API with Express using Cookie-Parser and/or sending the Token to the front end.
It works like this: the user makes a post request to the login route with the username and password, and if it matches, he gets back both a .json response with the token and a cookie set with the token.
I thought it would be nice for the frontend development and authorization purposes to have the current user available in every successive request after the login. So, I set a middleware that searches if there is a token, tries to find a user in database with the corresponding ID, and set the user info (without the password) as a parameter in the request object (req.user).
What I wanted to know is:
Is it a bad practice to put the user info in the request? Does it lead to security problems? Or maybe the database query in every request could overload the server if the app scales to much?
This is my first backend API, I'm trying out different ways of doing things, but I'm not aware of the best practices in the field. Any help is very much appreciated!
That is why there is encryption and in this context it is an ssl ticket. If you add login details to the request you NEED to make sure that the http response is encrypted. Once it is encrypted it is ok to do what you are doing. If it is not, an eaves dropper can snatch up that data from sniffing on your network.

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.

RESTful registration with activation email

I'm working on creating a REST API and one feature is to allow users to register. The general flow is the following:
The user specifies his email and password using the client application (SPA application) and presses the submit button.
A request to the API is made. The API adds the user to the database, generates a verification token and sends an email to the user.
The user verifies his email and clicks a confirmation link.
The API marks the user account as verified.
My question is regarding the confirmation link.
Should the link point to the client SPA application? In this case, the client application will make a POST request to the API with the verification token and the user email.
Also, how should the API know the link to the client application (the link needs to be added in the email and this is done by the API). Should the API store this link, or should the SPA client send the verification link to the API when sending the request to register the user?
Another approach would be for the link to go to an endpoint defined by the API. In this case a GET request will be made with the user email and verification token and the API will set the account as verified and inform the user that his account is now active.
I have read that this approach doesn't conform to the REST principles because a GET request should never change the state of a resource. In this case, the user resource will be modified.
I'm not sure which of the 2 solutions is better or if there is a better solution, so my question is what is the best approach?
Thanks!
Should the link point to the client SPA application?
If your 'Client SPA application' is the sole frontend for end-users, then yes: it should point there. Some people deploy a separate oauth2 / authentication server but that doesn't sound like it's the case here.
The client application will make a POST request to the API with the verification token and the user email.
The token should be enough. I'd avoid sending email addresses through urls.
Also, how should the API know the link to the client application (the link needs to be added in the email and this is done by the API). Should the API store this link, or should the SPA client send the verification link to the API when sending the request to register the user?
Both seem like really valid designs. If you want the API to be completely unaware of the front-end and support a multitude of frontends, it would make sense to me that the client sends their own endpoints. There is a security concern though, you don't want arbitrary clients to register arbitrary urls.
If you're just building a single frontend, I don't see a problem with the API knowing the activation url. It also sounds like it would be easy to change if your requirements change later.
I'm not sure which of the 2 solutions is better or if there is a better solution, so my question is what is the best approach?
Ultimately it doesn't really matter that much. Neither approach sounds like you're really painting yourself into a corner. Either you have a standard endpoint that uses a javascript HTTP request to activate a user, or you have a separate endpoint that redirects a user after activation. Both will work.

OAuth access token for internal calls

I'm currently tyring to build an API driven symfony2 web applicaiton.Just a basic application to learn symfony2 and REST.
It would be based on a RESTful api. Calls to the API will be authenticated using OAuth.
For e.g.:
if a client application wants to get data (information about all the fruits) through API it will need to make a GET request to the url and pass the access token as a parameter.So the url will look something like this.
http://www.mysite.com/api/fruits.json?=<access token>
Now the problem is that i would be needing the same data in one of my actions as well.
I need some help here.In order to get get data from above url in one of my actions i will also need to send an access token in the url.
How do i get this access token??
Should there be a fixed token which will be used for all such calls within my application??
You basic application project will grow manifold if you try to do what you want here.
Basically, you need to implement an Authentication Server for this.
i) First, the app should be registered for a scope;
ii) Using the app the user logs in to the authentication/authorization server.
iii) The server verifies if the app has access to the scope and if the user is registered in your system.
iv) Server creates an access token (which is a HMAC signed string) and returns to your app.
v) The app then hits the endpoint (restful API) with the token.
vi) The RESTful service then internally sends the token to the server and fetches the customerID for which the call is made and performs the actions that it's supposed to.
I wrote an answer once on how to create a OAuth Service/Provider - How would an efficient OAuth2.0 server / provider work?
Also, OAuth was designed such that client apps/3rd party software can access a user's resources on his behalf. A very simple example is = An app posting something on your facebook wall on your behalf. It is actually accessing a resource that you own (the wall) and posting to it. You do not need OAuth just to get some data - there are other ways to secure the API.

REST API and client on same server, need API authentication?

First, let me describe the application: we are working on a web-based software which is some kind of custom help desk application. It requires the user to login (we use FOSUserBundle). After login the user is redirected to the dashboard. From the dashboard there is no more page reload, the frontend is build on Angularjs and the user can get anywhere within the application without page reload. You could speak of a single page application.
So the data that is presented to the user, is fetched from a rest api (we use FOSRestBundle). This works quite well at this point.
There is some kind of dilemma. Only our staff will access this application (for now). So a staff member needs to login to access the helpdesk. The data that is pushed to the frontend via angularjs is called via api, so the user that has just logged in needs to authenticate again on every request because of rest.
Problem: Since the backend runs on symfony2 let us just try to get the user object of the currently logged in user when an api call is made:
$this->get('security.context')->getToken()->getUser()
returns anon. that stands for anonymous, or
$this->getUser();
returns just null.
So the authenticated context seems to be gone when using the rest api. However when I call an action directly without rest, I can get user information.
So what we need is to secure our rest api and get user information on every api call. We don't want third party people to access our application, just staff. I am not familar with OAuth, but the user will be redirected to a third party page to Allow/Deny access to his data? This would not be an option for us.
Based on that information, do you have any suggestions or ideas how to secure the api and transport the user data so that getUser does not return null or anon. but the actuall logged in user?
there's another way to resolve your problem.
It's by using Certificates.
you can generate certificates then use Http tunneling (https obviousley), the server will ask for a certificate (you've to configure Apache for that but it's not a big challenge).
with this in place, you've to add a CertificateManageron the server side to ensure that the certificate is valid and to know who's calling the service (to be able to authenticate the user at each request), the CertificateManager(or what ever you'll call it) will probably have to be configured within you filters chaine (as known in the java world), et voilĂ 
Hop that help you,
Abderrazak
REST is stateless so you will have to send some kind of authentication/authorization in each request. You can use HTTP BASIC AUTH or something like OAuth.
Have a look at https://github.com/FriendsOfSymfony/FOSOAuthServerBundle
I'm kind of building our application in exactly the same architecture (RESTful API with Symfony2 back-end and AngularJS frontend.
Another way is to duplicate the api routes, so that you have the api routes protected by OAUTH and the api routes protected by the session, both of them pointing to the same controllers. The method was explained here: https://stackoverflow.com/a/22964736/435026