How to stay logged in even when user force quits the app with Ionic / Cordova?

12,136

Solution 1

I've been thinking about this lately and I think I have an effective solution. I don't know anything about Rails but the idea should transfer. I only have experience in Mongo for a database so bear with me.

Every device has a unique identifier that can be retrieved in Cordova with device.uuid (from the Cordova plugin) or getUUID() (if you're using ngCordova). This id is only guaranteed to be unique for each platform, although it is likely to be unique across all, so you should add the platform and model to your unique identifier for good measure.

var deviceId = device.platform + device.model + device.uuid;

Now we have created a truly unique id that will never change and you don't have to deal with local storage.

Now imagine you have a collection or table of devices in your database that look something like this with the following key-value pairs.

{
    device: DEVICEID;
    loggedIn: true;
    userId: USERID;
}

Now when the app starts up grab the deviceId from the device and send it to your server to search for it. This will likely be different for you, just a simple key-value search.

var result = Devices.find({device: deviceId}).fetch();

In Mongo this will return an array of the results, there should only be one result though. Now we check to see if they were previously logged in and grab the userId.

var loggedIn = result[0].loggedIn;
var user = result[0].userId;

If they were logged out before or there were no results, take them to the login page. If they were logged in, run the normal login procedures automatically. The user id can be a sort of pointer to an object in another collection.

This is how I think I would do it, alternatively you can have the user object have the device id as a key, but a user can have multiple devices so it would have to be an array of keys, and I'm not sure how to search for that right now. Adding new devices would be as simple as adding the unique id to the collection and pointing it to the user.

Every time the app opens, it will check the device id and see if the user is logged in on the device. You can show a splash screen while this is happening.

Now if the user selects log out from settings you can update the database to reflect that and the next time they go to the app they will be logged out.

I hope my thoughts could be of assistance.

EDIT: I was thinking it might be better to delete the device object from the collection every time they log out instead of just setting the loggedIn, this way if they are getting rid of the device it won't remain in your collection. I'm not sure how removing objects often will impact the performance of the database though, but users don't log out of devices too often as far as I can tell so it shouldn't be too much of an issue.

This brings up another point though, used devices. This is an easy remedy though, every time a user logs in on an already existing device, update the userId key to the new user if it changed.

FURTHER EDIT (because I can't comment): On local storage/caching and why it's dangerous. The only thing that you could in local storage to automatically log someone in automatically would be their account credentials, which is highly sensitive information and should never be stored locally (passwords shouldn't be stored remotely either but hashing is a separate subject). You would never store their password in cache, you could make up some secret key and store it but anything accessible locally can be read by someone and potentially replicated on another device. The device id information would be much harder to fake.

Solution 2

Sorry, I'm unable to comment (need 50 rep) but I think using localStorage is a valid option here. You can create a JSON Web Token (JWT) and store it in cache.

On Android, unless you explicitly clear cache of your app by going into Settings, the app will keep your user logged in (i.e. not kill your cache) even if you Force Stop it or remove it from the multi-tasking pane. I'm not sure how it works in iOS.

I highly recommend this amazing Cache Wrapper by jmdobry

Also, there are amazing third-party libraries that can handle authentication for you:

I hope this helps! Good luck.

Solution 3

Not very secure, but you could use Cordova/JS friendly localStorage..

if ( logged_in_successfully ) {
  localStorage.setItem("email", email)
  localStorage.setItem("password", password)
} 
Share:
12,136

Related videos on Youtube

Austin York
Author by

Austin York

Updated on June 04, 2022

Comments

  • Austin York
    Austin York almost 2 years

    A common piece of functionality for native mobile applications is the ability to stay logged in even if the user closes the application in question (see e.g. the Facebook app on iOS).

    How can this be achieved for a Cordova / Ionic / PhoneGap app authenticating against a Rails backend via username/password?

    I'm using the devise_token_auth gem to facilitate authentication against Rails if that makes a difference.

    • Banik
      Banik about 9 years
      use localStorage.After login set username and password into localStorage and clear it when logged out. If you not log out and kill the app whenever you logged in check your localStorage key value is empty or not and then navigate to your page.
    • Banik
      Banik about 9 years
      @AustinYork I dont think so.On iOS it still keeps the data after killing,if you dont delete the app.
  • Arun Thapa
    Arun Thapa about 8 years
    This is too much effort just to make your login persistence and this wont event work if you are using token based authentication in API, Because your token will not last for ever on server end. Here is a better store those credentials in LocalStorage (ngStorage even better) and every time user lunch the app authenticate behind the scene if authenticated navigate to desire page or navigate to login page which make sense. Only time your localstorage won't have user credentials is during first login and when user mannually logs out.
  • Anil Sharma
    Anil Sharma over 6 years
    Try this way: localStorage.email = "[email protected]"; localStorage.id = "56";