I am developing an app that sends user-created data to a server.
Is it possible to recognise the same user when he is using the app on different devices without my app having to request access to his Google account, requiring additional permissions or asking him to create custom login credentials? (This is important as my app needs to work for 'anonymous' users.)
My app uses push notifications and, for any given user, I understand that the token ID generated by FireBase may be the same for each of his device installations of the app. So I am considering using these token IDs to identify the same user across multiple devices. However, I'm not sure how reliable that approach would be - or if there is a better way?
NB - I found Best Practices for Unique Identifiers (the Handling Multiple Installations section in particular), but it hasn't helped.
We can manage multiple installation with same account,
Generate device token using firebase
store token locally and on server also
on splash screen always check token stored locally with token stored on serever
if it shows differences ask user to keep only one device active to receive notification ,
if user selected current device store that token to server.
Related
We have apps developed for both Android and iOS which interacts with devices via BLE and uses a Spring boot backend server in which they have registered and logged in. They can log in with the same account on either Android or iOS (obviously). During the interaction we can get codes that the user may need in the future. To handle that we currently do this:
Android: Encourage the user to write the code down. Use the users login information (username/password) to generate a symmetric key which is used to encrypt data which is then sent to and stored in our server. That way, only the user can retrieve it and decrypt it. Drawbacks would be the way we generate the key in itself and the obvious fact that a user that has forgotten password/changed password cannot decrypt the data anymore.
iOS: Encourage the user to write the code down. Then store it in KeyChain with the kSecAttrSynchronizable attribute so it can sync to iCloud KeyChain. That way the user should be able to get it on any other iOS device. Obvious drawback is that if the user chooses to switch to Android then the code cannot be retrieved there.
Is there anyway we can store sensitive user app data for both platforms? We could store it in our server but since we want the users to encrypt it themselves (so we can't see the content of the data) we need some unified way. There is no magic Spring boot feature to store "encrypted user data" for a specific user which only that user can retreive?
Have thought about using Google Drive and store it in the hidden app folder. But I'm guessing that wont work with an iOS app that uses the Google Drive SDK?
EDIT
Just to exemplify:
A user buys the device and connects it to its Android app. The user then changes the reset code of the device which is what would be needed if the device was ever "factory reset" (of course not factory, but cleared). When that is done we encourage the user to write this code down/remember it. Then lets say the the user loses the Android phone and buys an iPhone. He logs in to the exact same account but now might need to reset the device in order to start using it again. If that code could have been stored somehow using the account (or using the users google account or anything) then he wouldn't have to remember it.
Is a new Registration Token needed for every platform of an app that a user uses?
For example, I login to Facebook from my phone's app and I also access it from the web. Would this require a single Registration token, shared by the different platforms, or would every platform still require its individual Registration token for a given user. Hence, a user may have multiple Registration tokens being used at the same time if they access the app from several different platforms?
P.S. I am specifically asking the question in reference to cloud messaging where a notification is generated and I want to notify the user on all platforms they are on.
If you have both a web app and a native app for a platform, and a user uses both from a single device, those two apps will have different registration tokens. The registration token is for the application instance, and each app (web/native) is a separate application instance.
My company that I'm interning at is currently using Firebase push notification tokens for authentication from the mobile app to the backend and I am not sure if this is a good practice. The way it works is as follows:
FirebaseInstanceID service issues a unique token for every device as
soon as device starts
Mobile user sends login info to server; if server authenticates, the
mobile app then uploads the Firebase token to the database and it is
stored with the user such that the token matches with the user
On any subsequent logins, user sends the Firebase token retrieved from FirebaseInstanceID service to the server; the server attempts to match the token with a user
On clicking logout, mobile phone sends an empty token (i.e. empty string) to the server with their associated username
I have a feeling this is a very bad way to do authentication but I don't quite know why. According to my research the conventional way to do is that the server sends a temporary session ID to client, client stores it securely, and sends it to server for any subsequent requests. Can somebody explain what's going on with this Firebase business and why its good or bad?
The problematic your company is facing, from what i understand, it to authenticate devices with a back-end API.
Actually when it comes to mobile applications, it is a tricky question. If users do not have to authenticate personnally, you still don't want to open your services to anyone. So you want to have an automated authentication system that runs in the background of your mobile app and that identifies devices or app instances.
To do that you need two things : 1 - identify a device (or an app instance) in a unique manner. 2 - make sure that the used string to identify the device/app instance comes from a real device/app instance.
Firebase instance ID is maybe right now the best free way to do that. The mobile app asks for google services to generate the unique token. The mobile app then sends the token to your back-end API for authentication.
And then the back-end API makes sure, during authentication, that the sent token comes from a real app instance by making a request to google services. Google services ensure that the token was generated on a real device (android/ios) and refer to an instance of your app (and not a tampered one).
This is a good way of delegating security issues that I exposed above to google services (who probably are better than you if you're not a security expert).
Of course there are other security measures that you should take to ensure your back-end API integrity. Such as HTTPS, for instance..
So I guess when it comes to mobile development, we should hope for a better solution than that, but since there are no better solutions, using firebase instance id is not bad practice.
Hope this helps
I'm trying to work out the best solution for a particular situation I'm in, and am having trouble working out the best option. It's a tricky setup, so might be a fun challenge for you Android experts! Here's my situation:
We have two Android apps already on the Play Store, and are working on another right now.
The two released apps are signed with the same keystore, but do not currently have a sharedUserId set in their manifest files.
The two released apps store a user's oAuth token in SharedPrefs, some product/content data in an SQLite DB, and some audio/video content in external storage (using getExternalFilesDir).
The apps are all separate oAuth clients/applications of our server (i.e. they all use different client ID and secret keys).
Our server is setup to only allow one oAuth token per oAuth application (i.e. Android app). e.g. if a user logs in to app A on one device, then logs into app A on another device, the first device's token will be invalidated and the app will receive a 401.
We've successfully implemented a single sign-on system on iOS by enabling shared keychain between the apps. If an app detects that another app in the group has a valid oAuth token, it can send that to our server and exchange it for a valid token for that app.
In the iOS version, we wanted to ensure that the apps didn't need to know about the existence of the other apps using hardcoded values per-app (e.g. if we release a new app in the future, other apps don't need to be updated to share/receive tokens with it), so we created an entry in the keychain containing an array of bundle IDs that had valid tokens, that all apps could access. When an app successfully logs in or exchanges a token, they add their own bundle ID to that array. Any newly installed app could find a bundle ID from that array, and use that it as a key for loading the token details for that app, which it would then exchange for its own fresh token.
We want the token exchange to be automatic and not require input from the user.
I hope that all makes sense!!! Please let me know if not.
I'm now trying to work out the best method for storing oAuth tokens (plus some additional data such as email address to go with it) on Android so that other apps owned by our account can access them in order to exchange for a fresh token.
I've looked into using the following, but am unsure of the best route:
SharedPreferences along with sharedUserId
AccountManager (https://developer.android.com/reference/android/accounts/AccountManager.html)
Android Keychain (https://developer.android.com/reference/android/security/KeyChain.html)
ContentProviders
The problem with option 1. seems to be that setting the sharedUserId after first release will lose access to all of the data (see http://java-hamster.blogspot.jp/2010/05/androids-shareduserid.html). This is not a nice thing for our users.
Option 2. (AccountManager) could be a good option, but if we want to store the tokens separately (per-app), but want any other apps we make to access their tokens, I'm not sure how we'd do that.
Option 3... is it possible to do what we need with Keychain?
If I understand correctly, option 4 would need each app to have its own ContentProvider? I'm not sure how that would work for our requirements.
If anyone has gone through this kind of situation and could share some insights and recommendations, I'd really appreciate it!
ContentProvider is probably your best best. I won't be able to provide the whole code for you to do this, but this is generally how I see it working:
Each app creates a content provider that exposes their own API token;
Each app tries to acquire and query (sequentially until successful) all the other content providers before requesting a login;
If app X is able to acquire and retrieve the token from app Y (via Y's content provider), then store it in app X and use it;
Side notes:
This is very sensitive information, so you should enforce security. Your content providers should only be accessed by other apps signed with the same key, they should have only read permissions and you should create your own custom permission as well.
The content provider does not need to access an sqlite database. It can access whatever your using to store the token (which I hope is stored in a secure way, but I'll leave that to your own judgment)
Useful links:
How to create a custom content provider
How to secure your content provider
Example of content provider that retrieves data from shared preferences;
AccountManager is meant to solve the exact problem that your are commenting. Here is a good tutorial to work with it:
http://blog.udinic.com/2013/04/24/write-your-own-android-authenticator/
Just be sure that you sign all your apps with the same keystore, because this is the only thing that might complicate things (a lot).
Using preferences will lead you into a problem as all that you store in the main thread is not guaranteed to be there in a Service (like a SyncAdapter). There used to be a trick for this in the form of flag (MULTI_SERVICE) but was deprecated in api 23.
ContentProvider is of course possible (its too generic) but AccountManager will help you to cover the corner cases related from refreshing tokens and other interesting stuff.
i'm building a facebook based mobile application.
every time a user is logging into my server, i want know which of his friends has accepted my application in facebook.
what i'm doing now is that i'm sending my server the list of the user's friend, and returning to him a list of whom from is friend is also a member of my application.
the problem is that this process is real slow when a user have lots of friends..
is there a way throw graph api or FQL to check to which applications a user (or his friend) granted permissions ?
Whenever you mark your app as native, Facebook disable the app access token from making API requests - this is a security measure to protect the developer and the users because most native apps will distribute their app secret, so it cannot be trusted.
That said, there is currently no way to retrieve a list of an app's users via Graph API or FQL. My recommendation is that you should track this at authorisation time - the point at which you get an access token for a user - because you can then store a full list of UIDs in your own database and not rely on the API for that list.
As a possible workaround (assuming you haven't been doing what I recommended above and have a number of users already), if you have stored access tokens somewhere, you could iterate through those and make a call to https://graph.facebook.com/me for each, which should give you the UIDs of all your app users. You may not have stored the access tokens centrally though, in which case I'm afraid you will not be able to get this list.