Obtaining FB password with users permission - ios

Is it possible to obtain a users fb password, with granted permission?
I'm using it in a project that allows users to keep their sensitive data locked using their fb account.
It's for an iOS application, and right now I'm able to collect a users email, through the Facebook iOS sdk, and password, through a login "workaround", but I'm not sure if the app is going to get rejected due to infringement of facebook's and or apple's legal rights.

No, it is not possible to obtain a user's Facebook password.
I am not sure if the app will be rejected but I would personally avoid this solution.
I suggest to use the user's facebookId instead of the user's email.
If the secured data are stored in the app:
You only need the facebookId.
If the secured data are stored on a server:
Of course, checking only the facebookId isn't secure enough because anyone with a precise facebookId could login with it and get access to the "secured" data on your server.
What you need is two parameter to identify a user through your app:
The facebookId of the user
A secret key
You can send the secret key in your header request (or as a URL/BODY parameter if you want). It ensures that your server is called by your app an not from another source (a hacker).
What I would do to be more secure is to hash these two parameters in SHA1 so that even your request isn't readable. Then all you have to do is compare on your server the same key hashed in SHA1 with the one received.
For hashing a string to SHA1, here is a link : http://www.makebetterthings.com/iphone/how-to-get-md5-and-sha1-in-objective-c-ios-sdk/

Related

Is authentication services capable to provide reset password and email verification and store user credentials

My use case is something like this.
I'm developing a rest api and single page web application.
But I don't want to store my user credentials (email, password) with me.
I want to store it in more secure place. From that place I need to verify credentials and issue tokens, as well as first time user register with the system that user's email ID should be verified and also If an user forgot his password there should be a way to reset it as well.
Finally in my node.js back-end I need to protect my routes from unauthorized accesses.
Do I can achieve all this things using a authentication service provider.
I go through the firebase docs and found It is little bit harder to implement my what I want using the firebase.
Is authentication services capable to provide reset password and email verification and store user credentials.
Or it just a token generator only?
If you are asking if Firebase Auth provides the ability to generate tokens for verified email/pass credentials it securely stores with email verification and password reset, the answer is yes. Learn more from their official documentation: https://firebase.google.com/docs/auth/web/password-auth
They also provide the ability to issue session cookies better suited for a Node.js server side managed sessions: https://firebase.google.com/docs/auth/admin/manage-cookies
You don't need to store the credentials. Firebase Auth will store them for you using industry best practices.

Should I check user auth ( user name , password, device token) in webservice every time when my mobile application is launch?

Should I check user auth ( user name , password, device token) in webservice every time when my mobile application is launch?
I currently developing an ios application that will need user to login with their username and password ( for the first time of application launch).
After that user information will save in app local data and user no need to key in username and password again.
My idea is to check if the user is still active-user by calling the web service whenever the application is launch.
My question is , is that necessary to check whenever the app is launch .?
And is there any design pattern to control the user auth for ios app.?
Generally, you should not store username and password locally, but if you MUST, then store it in iOS keychain and not in local app db. (If you are not familiar with keychain follow this tutorial)
To be able to 'not' save username and password in the app, you need to implement an authentication mechanism (like OAuth 2 : check this tutorial) which handles authentication via web view and needs client to only use the authorized token.
To refresh the token, you need a 'refresh token' api which can check if the token is valid and if expired you can prompt user to enter credentials or use the ones store in keychain to refresh the token automatically.
Note : you can find many more such tutorials on https://www.raywenderlich.com and elsewhere if you just google it.
Note 2 : Although OAuth 2 is more centered around giving access to 'third party', it is a good enough model for normal authentication mechanism. Please spare all the hate in comments for suggesting OAuth 2 for normal authentication.

Firebase - can't trust OAuth returned details?

The short version of this question is: If you use Firebase's OAuth capabilities to obtain a user's email address, do you still need to confirm/authenticate the user's email address yourself?
One of the usual benefits of using OAuth is that - depending on OAuth provider - you can get a confirmed email address, but is this really the case when using Firebase for a webapp, e.g. with a binding like AngularJS?
After a user authenticates, there seems to be two data objects - authData available to the client side, and auth available for security rules on the server side. While authData contains details such as name and email, but auth contains just a Firebase uid plus provider. Therefore, if I am to obtain that user's email address, it must be provided by the client, and hence can't (in theory) be trusted?
Based on my understanding of Firebase's documentation, if I were to use GitHub OAuth for my app, I'd need to do something like the following:
Get user's to log in/create account with Firebase/GitHub
Client JS retrieves the email address from GitHub OAuth response
Client JS "submits" this email for confirmation - could be done multiple ways
Email address should be saved in Firebase with status "unconfirmed" (such a field being read-only to the user)
I need my own server-side logic to process such email submissions and send a confirm email request, e.g. through something like Mandrill
I need additional server-side logic to receive the clicked confirmation and mark the email address as "confirmed" in Firebase
Therefore Firebase can help me with steps 1-3, but steps 4-6 need to be done via my own server-side code?
The answer to this question is therefore a Yes/No, but with some justification/explanation!
Thanks to #Kato for confirming my assumptions in the question were correct, so I'll explicitly provide this as an answer, as well as provide an alternative I hadn't thought of.
So the short answer is, "Yes, you need to obtain or verify the user's email yourself when using Firebase OAuth", and the steps I listed above is one way.
An alternate approach that still requires server-side code but doesn't require emailing, would be to have the user write their token to their users table entry and then have server side code use that to retrieve the verified email address from the provider themselves. e.g. with a GitHub authorization token and appropriate scope, you can retrieve the user's verified email and not then need them to verify it to you again.

Twitter and Reverse Authentication

I want to use Twitter to sign on in an iOS application. Once the user has authenticated with Twitter I want to pass these credentials to a server in order to match these with a user profile stored in a database.
I can comunicate with my server over https, but this still doesn't tell me that the credentials I am being passed from the app are:
Coming from the app - as someone else could start a secure session with my service
Have valid credentials - that the credentials are an actual signed in twitter account and not just some made up numbers (keys etc)
Do I need to implement reverse authentication to provide a method to do this securely? (If not what method should I use to know that the information provided is correct)
I think the methodology is once you got the token/secret from the iOS client is to call the GET account/verify_credentials, then you get the user account and you can compare twitter user id or name with the one stored on your user profiles.

Design for Facebook authentication in an iOS app that also accesses a secured web service

Goal:
Allow a user to authentication with Facebook into an iOS application which requires access to a protected web service that I'm running.
Assumptions:
There is a native authentication (and registration) system in place for those users that opt not to use Facebook for sign in.
Details:
Assume we want to offer the option for a user to sign in with Facebook without creating a separate account/credential for our system.
Because we support our own native auth mechanism (username and password) we have our own user IDs and issue an authentication token that is used for subsequent interactions after the initial credential validation.
I'm surprised that Facebook doesn't have best practices for this in their developer documentation. All the existing documentation is either assuming you are building FB auth into a website, or a standalone mobile app with no service that requires authentication.
Here's my initial thoughts on how this would be designed but want validation on whether it's correct.
Client pops the Facebook iOS Login
UI User signs in with Facebook credentials and gets access token
iOS App passes access token to our server
Our server talks to FB graph API using access token to (a) validate the token and (b) get the FB user ID for that access token.
e.g. Our server would call https://graph.facebook.com/me/?access_token=XYZ which would return profile info in a JSON object
Assuming it's valid, our server extracts the User ID from the JSON object and checks whether the user already has an account. If so, we issue our own auth ticket to client to use for that session. If user doesn't have an account, we create a new one with the Facebook User ID, assign our own unique UserID and issue our auth ticket.
Client then passes auth ticket back on subsequent interactions that need authentication.
This seems like the right approach to me but not sure if I'm missing something insanely basic and going down the wrong (complicated) path.
I just dealt with this myself, and here's the part that bit me:
In your step 5... It's possible for a user to register for an account with you entirely separate from their Facebook ID, right? Then some other time they log in with Facebook.... And you just created them a second account and lost their first one.
There needs to be a way to be logged in to your web service, then log in to facebook, and capture the association between the facebook ID and the local account.
Apart from that, your plan sounds solid.
Update: Facebook has added a doc outlining such a scenario HERE
Use https to transmit the auth token to your server, as stated by Facebook
Sharing of Access Tokens
Our Data Policies explicitly prohibit any sharing of an Access Token
for your app with any other app. However, we do allow developers to
share Tokens between a native implementation and a server
implementation of the same App (ie. using the same App ID) as long as
the transfer takes place using HTTPS.
One problem I can see with this strategy, is that somebody can give you an access token obtained for a different facebook app. As far as I know, there's no way to verify that the access token is for your application, so you'll just go on and use it.
It doesn't sound very harmful, though. Generally people/apps try to protect the access tokens, rather than sharing them.
One possible exploit of this would be, for somebody to create their own site or mobile app, obtain access tokens for their users and try to authenticate them, using your API. If this succeeds (the user is has a facebook account in your site), the malicious site will be able to use your API impersonating the user.
It's a bit of a long shot, but I think it could work.
Edit: It looks like there is a way to validate the access token after all. See the answer by #Daaniel on question Get application id from user access token (or verify the source application for a token).
your solution totally works.
Maybe an alternative: why not just get the email on the client from the initial social service request and send to your web service? The web service could just store the email, and maybe a social_provider as well. I understand that your web service will not be able to validate where the email came from, but isn't there a high-trust relationship between your web service and your client? If there is, seems like you can depend on the email coming from the right place. Someone please let me know what obvious thing I'm missing that makes the email-based approach silly...

Resources