11

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

  1. SQLite
  2. Shared Preferences. (I never used it. But I am assuming, we can use this)
  3. 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?

Marian Paździoch
  • 8,813
  • 10
  • 58
  • 103
Kevin Rave
  • 13,876
  • 35
  • 109
  • 173

4 Answers4

13

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.

Rob
  • 4,733
  • 3
  • 32
  • 29
  • I am confused about the 3rd para. When you store the data in Accounts, does it expire at sometime? That means, if the user is in the middle of the app, on some Activity, if Accounts does not give me U/P, I need to show the login screen to grab the U/P again? – Kevin Rave Aug 29 '12 at 05:11
  • @KevinRave He is taking about reusing access token from preferences – Jaiprakash Soni Aug 29 '12 at 05:14
  • The username/password will not expire. The authentication token returned from your webservice can expire (on the server side), if this happens you need to inform the AccountManager that the token has expired and that will trigger the callback instructing you to get a fresh token – Rob Aug 29 '12 at 05:15
  • @JaiSoni, The access tokens aren't stored in preferences when using the AccountManager – Rob Aug 29 '12 at 05:15
  • There is no authtocken mechanism here. REST calls need U/P in the header (Basic Auth) – Kevin Rave Aug 29 '12 at 05:16
  • So when they click on Logout, I need to wipe out the account details from the AccoutManager? – Kevin Rave Aug 29 '12 at 05:23
  • Basic Auth doesn't fit perfectly well with the AccountManager, you could hack it in by saving your U/P where the AuthToken would naturally go (put U/P into KEY_AUTHTOKEN in your override of confirmCredentials. – Rob Aug 29 '12 at 05:31
  • Yes if they click Logout you can wipe the account details from the AccountManager, or delete the Account itself. – Rob Aug 29 '12 at 05:32
  • It's worth mentioning that AccountManager doesn't implicitly encrypt passwords and just stores them as plain text. – Egor Oct 31 '14 at 06:48
2

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

Community
  • 1
  • 1
Matthew Quiros
  • 13,385
  • 12
  • 87
  • 132
  • Thanks. I want to know, if this is a standard way of doing it. Or there are better ways to do it. About logout? – Kevin Rave Aug 29 '12 at 04:39
2

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.

Jaiprakash Soni
  • 4,100
  • 5
  • 36
  • 67
0

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.

k3b
  • 14,517
  • 7
  • 53
  • 85
  • Is it accessible across the application, throughout the user session? – Kevin Rave Aug 29 '12 at 05:13
  • And not sure how you assign username and password to static members during run time? – Kevin Rave Aug 29 '12 at 05:14
  • It is accessable if you make it public. For details see [tutorial Understanding Instance and Class Members](http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html) – k3b Aug 29 '12 at 05:27
  • How do you instantiate / assign values for static variables at run time? – Kevin Rave Aug 29 '12 at 05:29
  • Just a thought--if you make the static variables public, isn't that dangerous because other apps will have access to it? How about protected, instead of public or private? – Matthew Quiros Aug 29 '12 at 07:49
  • @mattquiros the static variable is ony accessable within the same app. If you want single-sign-on for several apps the static member does not work – k3b Aug 29 '12 at 14:53