I am working on a Kivy app for iOS and Android and need help with keeping the user persistently logged in, even after the app is closed or killed. I am using Parse to store user
Below is the code that we ended up using to store the login info, which employs Kivy's JsonStore. The credentials can also then be encrypted using Python encryption libraries.
from kivy.storage.jsonstore import JsonStore
from os.path import join
class AppScreen(ScreenManager):
data_dir = App().user_data_dir
store = JsonStore(join(data_dir, 'storage.json'))
...
def login(self):
username = self.login_username.text
password = self.login_password.text
AppScreen.store.put('credentials', username=username, password=password)
And this is the code to retrieve the credentials:
try:
store.get('credentials')['username']
except KeyError:
username = ""
else:
username = store.get('credentials')['username']
try:
store.get('credentials')['password']
except KeyError:
password = ""
else:
password = store.get('credentials')['password']
In the .kv file, the username and password TextInput widgets look like this:
TextInput:
id: login_username
text: root.username
on_enter_key: root.login()
TextInput:
id: login_password
text: root.password
on_enter_key: root.login()
The answer is essentially that you must simply save the data somewhere. The details will depend on your requirements, and aren't specific to kivy - you can look up normal android or python practices.
I'm not sure exactly what android guarantees about permissions, but storing stuff in your app directory (on the main partition, not 'external' storage) should be inaccessible to other apps, though anything with root can view them. You can use normal python tools if you want to encrypt the data, and manage your own kivy gui for getting a decryption key/password from the user.
You could use the application configuration for that
edit for the comment:
basically, additionally to the normal def build(self): method you also add:
def build_config(self, config):
config.setdefaults('login', {'username': '', 'password': ''})
then, in your build method you can do the following:
def build(self):
config = self.config
self.username = config.get('login', 'username')
self.password = config.get('login', 'password')
now, after the user logged in successfully you just need to write the new username/password to the config:
self.config.set('login', 'username', input1)
self.config.set('login', 'password', input2)
Take in mind that this will save the password unencrypted. Perhaps you may want to add encryption for the password on your phone.
It will save the files to /sdcard/<appname>.ini. So you should really encrypt it because everyone with access to the sdcard will be able to read it!