Secure rest api with 3rd party login provider - facebook

I've got a web app that currently allows users to login via Facebook. This is the only login mechanism at present. I make use of the user id and the users friends to perform certain actions. Now I want to create an api that I can use to create a native mobile app. To do this, I would need to authenticate users against the api. I've looked at this question
Possible approach to secure a Rest API endpoints using Facebook OAuth
but I don't actually have a "user" table as I only pull the facebook info when I need it. In iOS or something similar I could obviously make use of the native facebook sdk and then call my api, passing in the required user id and friend ids etc. however I'm not sure then how I could specifically secure my api so that if a user got hold of another's user_id they could in theory retrieve info via the api or in theory any resource that only specific users should be able to see
I thought about creating an app_id and app_secret for all the separate apps consuming the api. I would then use the appropriate secret to encrypt the data being sent and returned. The api and native app would know the secret and be able to decrypt it and validate that a user can view the requested resource. Does this sounds like a valid approach? In theory only the native apps would then be able to decrypt what is returned from the api. Or should this really be done on a user by user basis as recommended in the linked post?
All of this would be done over https
Thanks

Not familiar with the Facebook API nor iOS so I am speaking completely in theoretical terms.
Could you not:
Ask the user to login with Facebook on the iOS app
Send the login data over a secure channel to your web application to handle the actual processing of the data
Send the iOS app a secure hash for authentication
Use your web application as needed; using the hash for authentication, make HTTPS requests as you would your web application and use the responses from the webserver to populate the iOS app
If you make a user_hash column a complex salted hash like a SHA-256 (or greater) hash, the user_hash will become invalid before anybody is able to guess the hash. You could save the user's Facebook credentials locally on the iOS device and then renew the hash every so often, as to invalidate old hashes and lock out perpetrators (like how a cookie expires). If the user hash somehow becomes invalidated while using the iOS app, the app will send the locally stored credentials and retrieve a new one.
If Apple offers cookies for apps, you could send the hash in a cookie from your webpage and give it a reasonable expiry time (e.g. 1 day). You'd be resending the locally stored Facebook credentials every day and be effectively locking out anybody trying to bruteforce your hashes. Use that instead of trying to implement cookies from scratch (if the iOS API offers that), but as I said, I'm unfamiliar with iOS.
From an SQL standpoint, your webpage would validate a user's Facebook credentials, create a new row with a randomly generated user_hash, expires timestamp, user_id, friends_id, etc. Every user that uses the webpage will have to send the user_hash either from their web-client or the iOS app and will be checked against the database. If the present timestamp exceeds the expires timestamp, the session is ruled invalid and the user cannot operate your application.
Of course, you'd need to encrypt the communication. Do you pass credentials everytime the user loads a page on your web app? Or do you store them in a session?
Hope this helps at least somewhat!
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSHTTPCookieStorage_Class/Reference/Reference.html

Related

Build a REST API available to authorized apps only (like Facebook) with Laravel

I'm building a REST API with Laravel and now I have an URL like
api.example.com/posts/3/comments
Now I'm wondering how to secure this API because as it's done now, anyone trying to make a GET, POST, ... request on this URL will get positive results.
I want this API to be available to authorized apps only (like Facebook API). For now, those apps are just my website and my iOS app.
I'm thinking about creating a table applications to store application's keys. But I don't know how to authenticate an app without publishing it key (which is obviously insecure).
Any suggestion? Thank you.
I would recommend that you use something like JWT. Using it, you create and store a token locally on the device, then every time someone makes a call to the server, you check the token and make sure that they are who they claim to be. You can store tokens for expiration if you like. They're typically used in stateless apps, so you will need to move away from the concept of a server session. You can use Middlewares to filter HTTP requests entering your application.

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.

Facebook, Node & Mobile app - pulling together

I'm trying to build a Facebook-authenticated native mobile app (Windows Phone) that connects to a web service I am creating in Node.
I'd like for a user to:
Log in to Facebook on the mobile app via a native UI or web window
If logged in successfully, create or access server-side user account data tied to that identity
Use the authenticated session to make subsequent authenticated requestsvto that user's data via the native mobile app
My question is: What's the best approach here?
Should I...
Log in the client to facebook locally in the mobile app and pass the Access Token to the node service, and then somehow map the user to my service data based on their facebook account id? That seems grossly insecure if I just pass that token in the URL.
Log the user in via a mobile browser window inside my app, and then redirect back to my Node service in the same window? How do I then make subsequent authenticated requests natively in my app?
Do something else entirely?
Sorry this is so open ended but this is the first time I have tied these things together and although there's a lot of info on each part I've yet to find something that describes the overall pattern / best practice for this design.
Your question is quite opinion based...but still I will try to help.
First of all, you can pass access token in url, its not insecure if you use https. Even if logged into facebook from your mobile app, than also its going to pass a access token in url only. If you mean having the token in http://something.com/access_token, than its not how its should be done.
If you look into the Oauth 2.0 draft you will understand that its done through setting a header Authorization with the value being the token and token_type. Take a good look at the draft.
As your solution I think its fine if you just use the first method mentioned in the question by sending the access token in header as I mentioned in your app and in turn authenticating that token from facebook on each request.
If you think this is just too long a flow for authenticating every request from facebook, than you can get access token by sending request from your mobile app to server and let the server handle the access token and store it in database which you can authenticate each request.
In any case take a look at Passport module, it has facebook and other auth built-in and should be sufficient for your needs.

Confused about an existing website with OAuth but now we add an API to the site

I'm writing an API for our product and I'm trying to understand how some basic OAuth works with regards to mobile apps that might leverage our (to be created) api.
Lets imagine that our website currently allows a person to LogIn to our site via Twitter OAuth.
On the callback from Twitter, our server retrieves the twitter OAuth result and if all good, then checks to see
if this user already exists in our DB (eg. lets assume the Email is the unique key). If they don't exist, we
create a new user.
Of course, we then log the user 'in', which means we create a cookie for them, for their browser.
So far - nothing new here. All normal stuff.
Now .. if we want to do this via an iPhone or Windows phone using their native language and the app's use our API, i'm not sure of the point where OAuth ends and our API takes over?
For example, lets pretend it's an iPhone app that takes advantage of our API.
The iPhone app will try to authenticate the user against their Twitter cred's. Ok, fine. But when it callsback, it's back in the phone, right? Not our servers. So then the app needs to try and create a new user? So then the iPhone might try and call /api/CreateAccount. But this means -anyone- can call this api? And how does the website really know they have authenticated? Only because the app says so? What's to stop the person from creating a malicious app and calling our API by flooding it with new account creations? And what about authentication to api resources? Forms Authentication isn't available here. So do people use querystring authentication over SSL for api calls? How does the iphone authenticate with -our- server?
I'm so confused.
Can anyone please explain the differences and common practices people are doing these days when they have a website and an api .. and use OAuth as the authentication mechanism, please?
The naive app would call not CreateAccount, but VerifyAccount with twitter's oauth set of data so you site and API could verify it. The site would respond with a unique userID and your iOS app would use that as it's internal user id. More info.

Secure communication between iOS client, Facebook API and server

I would like to implement an iOS app with Facebook login. I would like the users of my app to be able to interact with their social graph (i.e. post to their stream). For that purpose I would use the Facebook iOS SDK.
When the users are already authenticated with Facebook, they also should be able to use some services on the server side of my application. How can I verify a user against the services on my server?
In my iOS app I can query the access token (for my Facebook application) using the iOS Facebook SDK. Should I send that access token together with the facebook user ID to my server? Can the server verify whether the access token is valid? Or should only my iOS App communicate with the Facebook API? Can the server post to my Facebook wall, or should this be done exclusively throught the iOS app?
UPDATE:
Facebook now provides a security documentation / checklist:
https://developers.facebook.com/docs/facebook-login/security/
You have at least two options:
Send the access token to your Server and handle all requests to Facebook
using that token (if the token is invalid you get an error and just
pass it on to the client). => Safe but (a little) complicated.
Separate the communication between
your client (iOS App) and the Facebook API and
your Client and your Server.
Your app would handle all requests to the Facebook API through the Facebook iOS SDK and then communicate the resulting data, like all kind of Facebook ids, to your Server. This approach is totally insecure without some sort of encryption; you could send some cryptographic hash function to your server and validate it with a key stored on your server and the iOS App. => This method is (a little) easier to implement however less secure since the key can be stolen through reverse engineering. Moreover you would have to check the "I'm using encryption" check mark when submitting your app to the app store.
It actually depends on how much risk you are willing to take, what kind of requests you make, what kind of services you have and so on.
Can the server verify whether the access token is valid?
Yes, look here: Facebook access token server-side validation for iPhone app