I want to create a user account on first launch in a wizard and store that in a settings. Something like the account creation wizard in an email app. What is the best way to do?
Should I create a layout where I collect these inputs on first launch and store in Preferences?
A settings menu can be provided in the options key, so the Preferences can be edited.
Is that the right approach?
You can save user details in SharedPreference. Only concern should be security of passwords if you are saving it. Your application's shared preference is sandboxed by default, so your data is safe from other apps.. But a determined/inspired hacker with root access can get any data from any app in an android phone.
For password
1) Either you can use a web service, and store the password in server. During every login process, you can send the username/password to server and validate. This is the best approach if your application is using internet. This option has the simple advantage that you are not saving sensitive data on phone itself.
2) Other option is to store password encrypted. You can use this option if your app doesn't use internet one bit, and you are not ready establish a server for authentication process. There is no absolute security in Android, but saving encrypted does boost the security level.
Related
I have an app, that on the first start generates a random user id and password to set up an account on my server and store them in the shared preferences.
I am looking for a way to write this data into the cloud so that if the user installs the app on a second device it will retrieve this account data and use them on the second device as well.
On iOS, this is a trivial task but I am still trying to figure out how to achieve this on Android. I tried an approach with Firestore, but it seems to be able to write to the Firebase database, the user has to log in with Firebase. I assumed being logged in to a Google Account on the device would do this, but I still get invalid permissions back when writing data.
I do not want to force the user to a separate login.
Any ideas on how to approach this task? Is it possible on Android at all?
I have an app, that on first start generates a random user ID and password to set up an account on my server and store them in the shared preferences.
If you have your own server where you authenticate the users, and you also want to authenticate to Firebase, then I recommend you check:
Custom Authentication System
I am looking for a way to write this data into the cloud so that if the user installs the app on a second device it will retrieve this account data and use them on the second device as well.
You just should never simply store the credentials in Firestore. Storing passwords in cleartext is one of the worst security risks you can inflict on your users. You should either use authentication with your custom system or use one of the existing providers, like Google, Facebook, etc.
I tried an approach with Firestore, but it seems to be able to write to the database, the user has to log in with Firebase.
It's recommended to authenticate the user in Firebase before reading/writing data from/to Firestore because you can secure your database using Firestore Security Rules.
P.S. Don't store data in ShartedPreferences because this type of data is stored locally and doesn't persist application uninstalls.
What is the best and safest way to save user credentials on device for an android app.
I was thinking of encrypting data and saving it in preferences.
Is there a way similar to iOS keychain to save passwords?
The best idea is not to save them at all. Encrypting provides very little security in this case because the app itself has to have the decryption key, so the key and data are on the same device. It will prevent only the least determined attackers. An OS level device isn't much better, as anyone with physical access can easily get around it.
The best idea is to use an access token. Get the login data once, send it to the server to login, and have them respond with an id. Use that id in future requests to identify yourself. The server should remember who is associated with each id. Preferably the server will include a timeout mechanism, where after X amount of time the id will be invalidated and the user will need to log in again. Even more secure implementations will match it to some physical id of the device as well, such as the Android device id, requiring attackers to have the device or fake both pieces of information.
The use of an access token rather than saving credentials protects the users in a few ways. First, the attacker will not know the users password in case its reused for other services (like their email). Second, it will not be enough to change their password (because a secure service will ask for the password again to change it) so while the info in the account may be compromised the user can take back the account by using their password to change their password. If the actual password is saved and lost the attacker can change the login info and lock the user out of his account permanently.
If I want to store the username and password to be used inside an Android application, what is the best way to do it? Is it through the preferences screen (but what if the user misses this?), or pop up a dialog box and ask the user for the credentials? If so, I do have to maintain state for the application. How would I do this?
Most Android and iPhone apps I have seen use an initial screen or dialog box to ask for credentials. I think it is cumbersome for the user to have to re-enter their name/password often, so storing that info makes sense from a usability perspective.
The advice from the (Android dev guide) is:
In general, we recommend minimizing the frequency of asking for user
credentials -- to make phishing attacks more conspicuous, and less
likely to be successful. Instead use an authorization token and
refresh it.
Where possible, username and password should not be stored on the
device. Instead, perform initial authentication using the username and
password supplied by the user, and then use a short-lived,
service-specific authorization token.
Using the AccountManger is the best option for storing credentials. The SampleSyncAdapter provides an example of how to use it.
If this is not an option to you for some reason, you can fall back to persisting credentials using the Preferences mechanism. Other applications won't be able to access your preferences, so the user's information is not easily exposed.
You should use the Android AccountManager. It's purpose-built for this scenario. It's a little bit cumbersome but one of the things it does is invalidate the local credentials if the SIM card changes, so if somebody swipes your phone and throws a new SIM in it, your credentials won't be compromised.
This also gives the user a quick and easy way to access (and potentially delete) the stored credentials for any account they have on the device, all from one place.
SampleSyncAdapter (like #Miguel mentioned) is an example that makes use of stored account credentials.
I think the best way to secure your credential is to first think of storing the Password with encryption in the account.db file which couldn't be easily available in non rooted devices and in case of rooted device the hacker must need the key to decrypt it.
Other option is do all your authentication like the way Gmail is doing. after the first authentication with the Gmail server . you got the Auth Token that would be use in case of your password . that token would be store in plain text.this token could be false in case you change the password from Server.
the last option I'd recommend you to enable 2-Factor Authentication & create Device Specific Password for your device. After losing device, all you need is to disable that device.
Take a look at What is the most appropriate way to store user settings in Android application if you're concerned about storing passwords as clear text in SharedPreferences.
You can also look at the SampleSyncAdapter sample from the SDK. It may help you.
Take a look at this this post from android-developers, that might help increasing the security on the stored data in your Android app.
Using Cryptography to Store Credentials Safely
With the new (Android 6.0) fingerprint hardware and API you can do it as in this github sample application.
These are ranked in order of difficulty to break your hidden info.
Store in cleartext
Store encrypted using a symmetric key
Using the Android Keystore
Store encrypted using asymmetric keys
source: Where is the best place to store a password in your Android app
The Keystore itself is encrypted using the user’s own lockscreen pin/password, hence, when the device screen is locked the Keystore is unavailable. Keep this in mind if you have a background service that could need to access your application secrets.
source: Simple use the Android Keystore to store passwords and other sensitive information
The info at http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html is a fairly pragmatic, but "uses-hidden-android-apis" based approach. It's something to consider when you really can't get around storing credentials/passwords locally on the device.
I've also created a cleaned up gist of that idea at https://gist.github.com/kbsriram/5503519 which might be helpful.
All sorts of mobile apps - Gmail, Facebook, Pandora - have some persistent mechanism of authentication that enables a user to set up credentials once and then use them to automatically authenticate with their remote service in the future. I'm probably blind, but I can't seem to find a tutorial anywhere out there that explains in simple terms how to properly do this on a mobile app.
How do I build this functionality? A link to a simple tutorial would be great.
As Deva said, SharedPreferences is a perfect quick and easy solution for creating this feature. Usually when I want to implement this I follow this simple flow:
Logging In:
When the user logs in save the user id (it can really be any unique identifier) into Shared Preferences. This information should now be available so that your app can recall it later
Rebooting:
When the app reboots it should check to see if any user id is saved in Shared Preferences. If not, then there is no one to automatically log in. If there is, then reload the user information using the user id from the server or whatever.
Logging Out:
When the user logs out make sure you delete the key/value pair from Shared Preferences.
For this probabely you can try a SharedPrefrence. The first time user enters his details , the values get stored locally if the user is authenticated and every consecutive time you can check the same prefrence if the value is already there directly pick the value and invoke the service for authentication.
Apple's KeyChain is service ment exactly for such a scenario. it enables a persistent, secure and easy to use storage.
Good tutorial (+ demo application) here
I'm looking for something like the Keychain on the iPhone, but for Android development. Something that gives me the capability to save small key-value pairs that are persistent and unchanged even if the user reinstalls the application.
Is there something like that? Can I use the standard preferences that way?
I would like to achieve a behavior similar to the way it works with games on a PC - writing the save files to another folder so that after deletion and reinstallation the save files are not lost.
Edit:
The bounty ran out without somebody mentioning the accountManager. I just stumbled over it. Would that be a method to achieve the behaviour described by me?
You you use storage on the SD card like Michael Cramer stated ( Let the user know you are storing data :-) ). The data on the SD card is not deleted when the app is removed.
You could on the other hand use a server which stores all the details which can be downloaded as and when required and instead of using a user name use the IMEI of the phone which is unique. That way even if the user reinstalls the OS he will still be able to refetch the settings.
for getting the IMEI you may refer : How to get the device's IMEI/ESN programmatically in android?
You have the real thing here:
By integrating Smart Lock for Passwords into your Android app, you can
automatically sign users in to your app using the credentials they
have saved. Users can save both username-password credentials and
federated identity provider credentials.
Integrate Smart Lock for Passwords into your app by using the
Credentials API to retrieve saved credentials on sign-in. Use
successfully retrieved credentials to sign the user in, or use the
Credentials API to rapidly on-board new users by partially completing
your app's sign in or sign up form. Prompt users after sign-in or
sign-up to store their credentials for future automatic
authentication.
https://developers.google.com/identity/smartlock-passwords/android/
Since Android & iPhone-like phones will normally run with a data plan, I would suggest that you save your key-value pairs into a centralized server. When the app goes through the uninstall, followed by an install process, just resync it with your server.
Yes. Preferences are persistant and will survive a normal application upgrade.