I'm Creating a custom User Management system, involves all the App data to be on application server, but the phone should be authenticated by firebase. When New User Register on System, Firebase Phone Authentication takes place. On successful authentication from firebase, Registration Data goes to Server via API. Now the Problem is, how do I check server side that the phone number is authenticated by firebase or not? If I allow registration without server-side firebase auth validation, API Request can be spoofed by someone. I'm currently using kreait/firebase-php ^4.18 Firebase SDK for PHP.
The Flow I'm Using Right Now is Demonstrated below and the flow I want to implement is also can be given as,
Update 25/09/2019
The library Kreait\Firebase helped to achieve to implement flow as given in answer by #jeromegamez in the accepted answer, However, the Kreait\Firebase does not support the idToken validation for ios device.
IOS device has google idToken rather having firebase IdToken and hence Kreait\Firebase failed to validate it. Brief issue is given in Firebase IOS idToken invalid kid Exception in the backend while verifyIdToken in Gmail Auth post.
The Firebase Rest API has the method for that.
On the device, after the user is authenticated and you have the User object, to get the token for verification, you can call
with Android - getIdToken()
with iOS
Swift - getIDToken()
Objective-C - -getIDTokenWithCompletion:
with JS (web or other platforms) - getIdToken()
with React Native - getIdToken()
and bunch of other platforms in the docs
Then, with that temporary id token, you can send a POST request to https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=[API_KEY] (API_KEY being the "Web API Key" of the Firebase project) to get the user info, which will include the phoneNumber of the owner of the token.
Thus you can verify server-side that the owner of the token has that specific phone number.
When a user successfully authenticates with their phone number for the first time, the phone number is stored in the user's record in the Firebase Auth User list and can be considered verified.
Once a phone number is associated with a user in your Auth database, you can be sure that
the phone number is valid
the phone number has successfully been used to authenticate the user at the point in time the number has been associated with said user
the phone number cannot be associated to another user
You should not assume that this phone number is now "verified". As stated in the official Firebase documentation pages:
Security concerns
Authentication using only a phone number, while convenient, is less
secure than the other available methods, because possession of a phone
number can be easily transferred between users. Also, on devices with
multiple user profiles, any user that can receive SMS messages can
sign in to an account using the device's phone number.
If you use phone number based sign-in in your app, you should offer it
alongside more secure sign-in methods, and inform users of the
security tradeoffs of using phone number sign-in.
Source: https://firebase.google.com/docs/auth/web/phone-auth#security-concerns
PS: The only other way to add a phone number to a user is through an Admin SDK, and here it's your responsibility to ensure that the phone number belongs to a user.
PSS: As far as I know (and checked), the Firebase REST APIs don't expose a "verified phone number" information.
Related
Firebase phone number verification authentication is triggered by the user from the client-side SDKs on my website I am developing. Is there a way to write code such that the firebase api:
a. sends SMSs to only registered phone numbers (existing registered users) and
b. not send SMSs to unregistered phone numbers (anonymous users)?
This is to prevent data abuse by anonymous users to my website.
There is no way within the Firebase Authentication API to limit what users can authentication through SMS, or any other provider.
The logic here is that in order to know whether a user is authorized, you first have to know who that user us, which already requires them to authenticate.
This does indeed means that a malicious user can make calls through the API with your configuration data. You'd then typically prevent those users from accessing your application by a further check, for example by having the list of approved phone numbers you mention. The difference is that this check happens after the authentication step, and not as part of it.
Firebase has abuse prevention methods in place already, so there's usually nothing you need to do beyond calling the API and protecting your backend resources. If you suspect you're seeing abuse on your project, reach out to Firebase support for personalized help in troubleshooting.
Scenario: I want to create an app where users register accounts and a server sends them a one time pin to verify their contact details via SMS. User enters the code received to verify their details.
However, sending an SMS costs money but receiving one is free and my SMS gateway lets me read incoming SMS messages.
So I could create a screen in my app that lets the user send an SMS to my gateway with the gateway number and message prefilled (eg. "Hi, please activate my account with code: 34GKTT551T"). User only needs to press send.
Instead of having the user type in a code they've received and verifying the code on the server, my gateway picks up a code sent by the user and sends the message to my server which then verifies the code and thus validates that the users phone number is the one they entered on registration.
Question: Is there anything fundamentally wrong with this approach?
What are the pros and cons of doing things this way? Yes, I know SMS messages can be faked but it's harder than faking an email which could also be used. I would not consider this an alternative to proper 2 factor authentication but this approach worth doing as a lower cost alternative that doesn't require users to do anything else special.
PS. This is my first question on stack overflow so be nice.
No this is not secure as the sender of an SMS can be easily faked. Take these instructions for how to achieve this on Kali OS.
There are also services such as this one.
All it would offer is a very thin layer of security against people who have the user's password but do not know the above information or the mobile phone number of their victim. The phone number of their victim may be achieved via other means such as social engineering. It may work if there is a separate phone used for the sole purposes of 2FA, however why not go with using Google Authenticator API, which is free (Google Authenticator app available for iOS and Android)?
I was following these articles: Verifying Back-End Calls from Android Apps and Stopping Vampires using License Verification Library (from 24:57 to 25:34) to implement an In-App Purchase verification system for our Android apps.
I am a bit confused about how this works end-to-end and what we can assume about the generated token from calling GoogleAuthUtil.getToken() with the first email address found--when AccountManager returns more than one account. My questions are as follows:
Should we assume that any e-mail address used by the user to buy our
app will generate the same token (i.e., same user + app ==> same
token)?
If the answer to question 1 is no, is there a way to launch in-app
purchase for a particular account/email?
It looks like Google is picking the first e-mail address returned by
AccountManager for its in-app purchase dialog. Can we assume that
this won't be changed by the user after in-app purchase dialog is
launched? How do we find out if this changed after the in-app
purchase returns?
What should we store in our database to identify this user? Is email
address and/or token allowed? When does the token expire?
The java-client library looks very promising and powerful at first
read. But, a number of things remains confusing. Is there an article
that describes the end-to-end scenario--from an app initiating a
call to a back-end server through launching the in-app purchase
dialog, getting the result and closing with commits on the server?
What articles are the most useful for accomplishing this on Android?
The main issue we are trying to solve is to to get the full picture.
We've gotten the idea that we can avoid requiring userid/password by using the java client features and using tokens. We have registers our project (both the web app and android app on the same project) per the instructions for Google API Console. We have the php java-client for Google Play Service on our back-end server. We got our Android app to generate a token using the first email address and then call the in-app purchase dialog and handle the user response at the end of the dialog. We've got the parts. Now, we need to glue everything together. We are at the point of integrating with the back-end server. E.g., What is Redirect URi supposed to point to in our server? We've got a php url that we do http post messages to for our server app. We've included the code example for Google API client example--with client-id, secret, simple api key, etc. filled in--as an include to our php. But, what should we put in the redirect uri (we are missing a usage instruction for the example code)?
Also, we want to avoid having the e-mail used for the in-app purchase be different from what we log on our server database as the address the user used to buy our app; if the address is the correct thing to track, we want it to be the same as what was used for the purchase. This could be frustrating for our user if we make this mistake and prevent them from the features they paid for. We don't want to make this mistake and need some clarification on how Google Play Service works. If we initiated the server part of the workflow to get app Nonce / Payload / Credentials for the first e-mail address on the Android device, we would want that address to be used throughout the workflow. If the user changed this along the line, we want to be aware of this and gracefully recover. So far the articles have been helpful but incomplete. Any insight/suggestion is appreciated.
We have a request from a client to update facebook status/comments through a text message.
Here is the scenario.
The SMS carries the fb Username,Password and the status/comments and this will goes to a SMS Gateway. Then the USername,Password and the status/comments come to our application and our application should facilitate to update the status and comments on the fb account.
Is there a method to authenticate the user through a SMS (Auth Dialog box) or is there any other method to update status/comments on fb through a sms. This is a PHP application.
Why don't you ask your user to create an account on your site and authorize your Facebook registered App to access his timeline? He would also register his phone number on your site and get a short numeric unique ID.
Then he can just send an SMS and when you detect a phone number or the numeric ID in a SMS, you post with the Facebook API which you are authorized for.
Sending Username and Password via SMS is not a great idea. A numeric ID of the phone number itself is much safer.
PS: I'm not using FBAPI but this is how it's supposed to work, from what I heard.
it is not possible to authenticate using username and password.
you should ask your users to create new application on their profile or authenticate first via your website in order to grant you an access.
after obtaining application_key and application_secret you can manipulate with user's account using these pairs.
please refer to facebook's developer zone to get more details on how fbapi works.
Regarding C2DM, if I have a phone and another device (another phone, potentially a GoogleTV, etc) and I setup a C2DM server, will I receive two different Registration ID's that I can then use to send intents to both devices?
What seems like it may happen is this: I register one device and I receive my ID. Then I register another device and I receive a different ID which invalidates the first. Is my assumption correct?
I don't want to do a lot of development only to find out that a user's account can only have one Registration ID active at a time.
Yes, you will receive different registration IDs on each device. The Google account on the device is not used for registering with C2DM. The registration ID is used to send a notification to a particular application on a particular device.
More information about how the registration ID is constructed can be found in this thread from the android-c2dm Google group.
You need an active Google account on the device so that the transport underlying C2DM is active (the same mechanism is used by Google for Gmail and Market notifications).