I use token based authenticated mechanism on my server. When user logins through Android app the server returns token which needs to be sent with each subsequent request. I need to store that value on the devices. Since token is a simple string, I thought I'd use SharedPreferences to hold that value. When application starts inside MyApplication extends Application I query SharedPreferences for this token and hold it inside MyApplication as a global state so that every activity could access it when it sends request to the server.
Is this approach viable? If not, what critical drawbacks does it have? And if it's a bad idea, what's the alternative approach?
PS. This is not a subjective question - I'm not asking for the best approach, I'm validating my assumptions.
It's fairly safe. The users wont have access to the SharedPreferences unless they have rooted their devices. If you're concerned about security that much, you could encrypt the token before storing it inside SharedPreferences.
it is a valid option, if you don't want to use a database or write the token on a file. No drawbacks that I can think of
It has one fault if the device is rooted. The user can see the token from SharedPreferences from their device if the device is rooted. I suggest you to store the data to the database/SQLite using Sugar here for better approach to your server.
Related
I am not sure of the best way to do this, when user logs in my app i want to store his data from an api. I will be using this data trough out the app, so i dont call getUserData all the time . So i want to ask for an opinion
Do i store user data in application context so i can access it in all activites/fragments
Or
Do i store the user data in SharedPreferences as json string (User has a lot of small data name,lastname,age,email...)
Or
Do i store it in database (Since i only need storing for this i tought this way might be too much, but could be wrong)
Or
There might be a better way to do this?
SharePreferences are great, but it is stored in plain text and can be read by rooted devices. Someone with a stolen rooted phone can potentially access tons of user info.
Use a library like:
https://github.com/scottyab/secure-preferences
To encrypt the preferences or use a secret key to encrypt and decrypt the data.
You can initialized the user object on the OnCreate of your Application Object this way. Have you app instance be a singleton and you can access this user object object amongst your activities and fragments.
I need to perform login against a REST API webservice.
I POST username/password and, if they are right, webserver returns a me a token, to use for every call.
I'm going to save this token in EXTRA, and recall the EXTRA from every intent that I will call. Am I right? Or I need to use the sharedPreferences ?
Thank you
Depends how you want to store that token.
SharedPreferences writes to internal storage.
A Singleton or similar would keep that token alive in memory, but won't be kept across instances of your application.
Same for EXTRA as Singleton.
Best practice would be IMHO to keep the token in memory and request a new one at each startup of your application, for safety.
In this example they, as far as I understand, do something like this:
https://developers.google.com/cloud-messaging/android/start
git clone https://github.com/googlesamples/google-services.git
1) Upon app start request the token and save it in Preferences
2) Make calls using this token until server refuses the token
3) Request a new token upon server refusal
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Okay. I started developing an Android App for our enterprise web app. Just started the Login screen activity design.
This app is completely driven by RESTFul API.
I would like to understand how to develop login / logout feature in the application.
As far as I understand, there is no Session concept in the app world. Also, for the API, we need to send Username and Password with every request (Basic Auth). So apparently, we need to keep the login credentials somewhere in the local storage to send along with every request.
Here is what I understand from my basic Android knowledge.
When user enters login information and presses the button, we'll spin up a HTTP call to API. If login credentials are valid, then we'll have to store the credentials locally. Options are
SQLite
Shared Preferences. (I never used it. But I am assuming, we can use this)
Bundle (Not sure if this is an option)
Any other alternatives?
I want to make sure I follow the best practice, while not sacrificing from performance and architecture perspective.
And for the logout, I think I just need to wipe out the credentials stored locally and show login Activity.
Are there any different and better approaches?
I would suggest making use of the Android Accounts feature.
This blog has a pretty good step by step guide on all the bits you need to put together.
The general idea is you supply the AccountManager with the users username/password, and leave it up to the AccountManager to store them securely.
When you need an authentication token, you ask the AccountManager for one, and it will either return a cached token, or call back into your code (passing the username/password) and you make the call to your authentication service to get a fresh token.
I think storing password in app is bad idea, better approach is just make request with user credential at first time when user get login the server return an access token save this access token in SharedPreferences for rest of purpose like getting user detail use the token in request.
Session : Create your own class for maintain session. Hackbook is a good example for it.
Generally, there are three ways you can persist data in Android: SQLite, SharedPreferences, and reading/writing onto a file a la Java I/O. SQLite is optimal for relational data, but because you simply need to store the user's credentials, I recommend you use SharedPreferences. It seems to me like a simple key-value data model.
SharedPreferences are basically just an encapsulation of direct file I/O--that is, the underlying implementation is still file reading and writing, but simplified for key-value pairs. I don't know much about encryption, but you might have to handle that yourself before storing the password in a SharedPreferences object (also consider JaiSoni's suggestion: use an access token instead). Rest assured, however, that if you create the SharedPreferences and set it to MODE_PRIVATE, other apps won't have access to the shared prefs file.
I believe this is pretty much a standard implementation. If you look at this page, there's really only so much you can do: http://developer.android.com/guide/topics/data/data-storage.html
May I also point out that one of the complexities with direct file I/O is that you'll have to decide where you want to store the file--internal or external memory (e.g., SD card)--and hence check for its availability (not all devices have SD card slots, and sometimes internal memory is registered as external memory to the device). So just go with shared prefs.
For logging out, this might be useful: Deleting shared preferences
Why do you need to persist the login credential in a file or database? do you want to be automatically logged in after your app is restarted? if persistance is not necessary you can put the credentials into a static java member.
I have created an Android app that communicates with a PHP web server. They both send JSON to each other. My app is almost finished, however there is one thing left to do: authentication.
Since the user's username and password will be stored in Android SharedPreferences, is there any need to use PHP sessions, given that the user won't need to enter the username/password at every request?
Since I can just send the username and password in the HTTP POST header for every request, and that I will be using SSL, is this sufficient? I guess I could add an extra field in the header called 'random' that just adds a random value, just to use as a salt so that the encrypted SSL payload will be different every time.
The reason why I don't want to use sessions is that my Android App would either have to handle cookies, or managed the storage of the session ID.
If there are some serious cons to using my method above, then I'm more than happy to use sessions.
Personally, I'm against sending the username and password in the request each time. One thing you could do is generate a unique ID when they log in, and store that in a database on your server, then just pass that instead of the username and password.
I think Google have given this a lot of thought, so doing something similar to what they do wouldn't be a bad idea. If you look at the way they do their
login process, i.e. https://accounts.google.com/o/oauth2/auth
and especially their
token freshining, i.e. https://accounts.google.com/o/oauth2/token
it might feel like overkill, but you might come away with some ideas that could be valuable to your own implementation.
EDIT: oops, almost forgot the documentation link: https://developers.google.com/accounts/docs/OAuth2
I believe that you will be fine with what you have now. As long as you make sure that the user info is securely transfered. The salt is a good idea. It really just depends on how secure you want it.
It is very bad practice to send account credentials in every request.
I think the better way to use Google OAuth2 API - it is VERY simple and safer than local accounts database. Have you considered that option?
What is a good practice to save username and password on device?
I have gone through many answers on StackOverflow and now i am bit confused.
I am working on an email app and i want my user to feel absolutely safe while using it.
Some people suggest that we should encrypt it and save it in SharedPreference. Some suggest we shouldn't save it on device at all.
I just want user's details to be stored at safest place possible.
Any help, suggestions would be highly appreciated.
You should save users credentials using the AbstractAccountAuthenticator class. Not only is this super secure, it also makes your app feel more integrated with android. Have you ever gone to the "Accounts" screen in your android setting and seen your Facebook, Twitter, and GMail accounts there? That's because they're using an AccountAuthenticator. Also, it allows you to associate URIs/ContentProviders with particular user accounts. To see a really comprehensive (but complicated) example of all this, checkout the SampleSyncAdapter example.
Do you have any control of the server side, or is this a generic email client? If you can control the server side, I would do something like authenticate, then have the server generate a UUID and keep that locally to future api calls. Another idea would be to send a hash of the password to api calls instead of the actual password, then you can store just the password hash locally.
The issue with encrypting the username/password is that your code needs to be able to decrypt it, and if your code can decrypt it, somebody can reverse engineer your code and do that as well, although you can make it easier/harder by how you code and package it.
Once you figure out WHAT you're storing, you can figure out how you store it. One account? Shared prefs. Multiple accounts? Create a Sqlite DB.
I would suggest using http://ormlite.com/ to handle your db connections. I did a good chunk of the initial Android port work, and its now been enhanced/maintained by a top notch group of hackers. Very solid stuff.
See more Sqlite blog posts:
http://www.touchlab.co/blog/single-sqlite-connection/
http://www.touchlab.co/blog/android-sqlite-locking/
If security is a concern, eventually it still boils down to saving the user credentials in encrypted form. Here are some suggestions:
Consider encrypting the credentials using Base64.
The encryption key should be divided into different parts and saved in different parts of the app. Only to be combined by app logic.
Consider using JNI for encryption part of the code.
Once you have an encryption logic in place, you should use AbstractAccountAuthenticator.
Remember two things:
a. An apk can be decompiled to retrieve the key. (Thats why (2) and (3)).
b. Saving plain text is disastrous. (Thats why (1)).
On second thoughts, once you have 1, 2 and 3 in place, you may use SharedPreferences as well.
SharedPreference is the best option.
Ease of Use
Only deleted when user clears data for the App
Flexibility to change values when user uses another set of login credentials.
Here is how you can do it.
import android.preference.PreferenceManager;
private static final String LOGIN_EMAIL = "login_email";
private static SharedPreferences mAppPreferences;
private static SharedPreferences.Editor mEditor;
/*Insert your code to Get user entry of email from the EditText*/
mAppPreferences = PreferenceManager.getDefaultSharedPreferences(context);
mEditor = mAppPreferences.edit();
mEditor.putString(LOGIN_EMAIL, v_user_email );
mEditor.commit();
I don't think SharedPreference storage is unsafe or can be tampered with.