miércoles, 24 de abril de 2013

Cuentas en Android Parte I


Por padron, Android incorpora un Account manager, el cual es usado para guardar las credenciales de los usuarios y sincronizar los datos con el servidor (de ser necesario).

Account manager es un servicio centralizado por android (En vez de tener una cuenta por cada servicio que tienes, es mejor tener una sola que te de acceso a todos los servicios. Un ejemplo es Google, con las credenciales de google puedes acceder a Youtube, Gmail, Google+ usando las mismas credenciales, esa es la idea de servicio centralizado). Cuando se crea una cuenta, de tu empresa o de otra cualquier aplicacion puede cojer la lista de cuentas y con el usuario utilizar su auth tokens asociado.

Basicamente se tiene una lista de las cuentas, cada uno identificada por:

Account name: El nombre del usuario para login. Ejemplo: titusfx
Account type: El tipo de cuenta. Por ejemplo: com.google

Todas las cuentas deben ser unica. Esto es por, dado un dispositivo, no pueden haber dos cuentas con el mismo nombre y el mismo tipo de cuenta.

Por cada cuenta, hay un conjunto de datos relacionados:

Password: La contraseña de la cuenta. Esta puede ser vacio ("").
AuthTokens: La cadena usada por el servidor para identificar el usuario, en ves de usar la contraseña. Normalmente el auth token es temporal y expirara despues de un tiempo. Todos los auth tokens tienen un tipo llamado AuthTokenType. Esto es porque una cuenta puede usar varios servicios, y por cada servicio debe haber un auth token diferente. Por ejemplo, una cuenta de Google puede ser usada para Gmail y Youtube. El authTokenType de Gmail es "mail" y el the youtube es "youtube". Más informacion. 

UserDatas: Ademas se puede salvar informacion adicional con un par de cadena a estilo de diccionario ( par llave/valor ). Por si se quiere guardar informacion adicional que es utilizada por las applicaciones.

3. Permisos

Hay varios permisos que son requeridos para interactuar con el account manager:

android.permission.GET_ACCOUNTS 

Este permiso es utilizado para tener acceso a la lista de cuentas y chequear si una cuenta especifica  tiene una especifica caracteristica(feature). (Los features no seran debatidos en este post.) 

android.permission.USE_CREDENTIALS 

Este permiso es para utilizar e invalidar auth tokens. 

android.permission.AUTHENTICATE_ACCOUNTS 

Este permiso es utilizado para modificar la informacion relacionada con la cuenta, tal como la contraseña, los datos del usuario, los auth tokens, etc. Es usado para crear cuentas y acceder a la contraseña.
android.permission.MANAGE_ACCOUNTS 

Este permiso es utilizado para adicionar or eliminar cuentas. Este puede ser necesario cuando la aplicacion utiliza alguna caracteristica avanzada de la aplicacion como actualizar credenciales o editar propiedades.

4. Manejando informacion con account manager

4.1 Account manager

Una aplicacion no puede crear un nuevo account manager pero puede coger el existente pasando el context de la aplicacion.

AccountManager accountManager = AccountManager.get(Context);


4.2 Accounts (Cuentas)

4.2.1 Agregar una nueva cuenta

La manera mas facil de adicionar una cuenta es utilizando el metodo:

boolean addAccountExplicitly(Account account, String password, Bundle userdata) 

Note que la clase Account puede ser facilmente contruida con:

Account account = new Account(userName, accountType)

Ambos parametros son Cadenas, uno es el nombre del usuario y el otro el tipo de cuenta.

4.2.2 Acceder a una cuenta

Una aplicacion puede cojer informacion acerca de todas las cuentas del systema. Hay dos metodos principales:


Account[] getAccount() 


Account[] getAccountsByType(String type)


El primero devuelve todas las cuentas del account manager y la segunda, solamente devuelve las cuentas que encajan con un especifico tipo de cuenta.

Todas las cuentas tienen dos tipos:

name: Accesible usando account.name
type: Accesible usando account.type

Luego, una forma facil de acceder a una cuenta de tipo "com.jiahaoliuliu" que el nombre del usuario es "jiahaoliuliu":


Account[] accounts = accountManager.getAccountsByType("com.jiahaoliuliu");

Account myAccount = null;

for (Account account : accounts) 

{

    if (account.name.equalsIgnoreCase("jiahaoliuliu")) 

    {

        myAccount = account;
        break;

    }

}




4.2.3 Eliminar una cuenta
Las cuentas pueden ser eliminadas por:

AccountManagerFuture removeAccount(Account account, AccountManagerCallback callback, Handler handler)

Note que, por cada cuenta, puede existir una configuracion que la prevenga de ser eliminada. Lo que no garantiza que siempre se pueda eliminar la cuenta.

4.3 Contraseña

La contraseña es una informacion sencible no deberia ser guardada de la manera que es. uno de los grandes problemas de seguridad es guardar las contraseñas como texto plano sin ningun tipo de encriptacion. Verifique la seccion de seguridad en la segunda parte de este post.

4.3.1 Assignar la contraseña

Dado una cuenta, la contraseña puede ser asignada de dos maneras:

Cuando una cuenta es creada por la primera vez, usando el metodo:

boolean addAccountExplicitly (Account account, String password, Bundle userdata)

Después que la cuenta fue creada

void setPassword(Account account, String password)

4.3.2 Acceder a la contraseña

Se puede acceder la contraseña por el metodo:

String getPassword(Account)

4.3.3 Limpiar la contraseña

Hay un metodo especifico para limpiar el password.

void clearPassword(Account)

El metodo siguiente tiene el mismo efecto:

setPassword(Account, null)

4.4 Auth tokens

Como se ha explicado anteriormente, una cuenta puede tener un conjunto de auth tokens, cada uno para un servicio especifico que se identifica por authTokenType.


4.4.1 Asignar un auth token

Para asignar un auth token, se puede usar el siguiente modo:

void setAuthToken(Account account, String authTokenType, String authType) 

4.4.2 Acceder a un auth token

Hay varias maneras de acceder a los auth tokens. La manera mas facil es la siguiente:

AccountManagerFuture getAuthToken(Account account, String authTokenType, boolean notifyAuthFailure, AccountManagerCallback callback, Handler handler) 

Aqui hay un buen ejemplo de como usarlo

4.4.3 Invalidar un auth token

Normalmente los auth tokens tienen un tiempo de expiracion, es una buena practica invalidar un auth token una ves que esta ya no es valida. Para hacerlo se usa el siguiente metodo:

void invalidateAuthToken(String accountType, String authToken)

Note que para usarlo debe entrar el authToken completamente.


4.5 Informacion del usuario

Ademas la aplicacion puede introducir cualquier informacion extra relacionada con la cuenta pasando. Es un diccionario de llave/valor donde todos son cadenas.


4.5.1 Asignar la informacion del usuaio

Como la contraseña, la informacion del usuario pueden ser introducidas cuando la cuenta empieza a ser creada o despues de ser creada.

boolean addAccountExplicitly(Account account, String password, Bundle userData) 

despues de ser creada:

void setUserData(Account account, String key, String value)


4.5.2 Acceder a la informacion del usuario
Solo hay un metodo para acceder a la informacion del usuairo.

String getUserData(Account account, String key) 


4.6 Un account updated listener

El account manager ofrece la posibilidad de adicionar un account update listener para actuar cuando una cuenta es actualizada. El evento (listener) sera aplicado a la instancia actual del AccountManager.

void addOnAccountsUpdatedListener(OnAccountsUpdateListener listener, Handler handler, boolean updateImmediately) 


void removeOnAccountsUpdatedListener(OnAccountsUpdatedListener listener) 

Es importante notar que mientras una instancia de Account manager empieza ser escuchada, este no va ser recogida por el account manager, ni el context usado para devolverlo. Para evitar fuga de memoria, es importante eliminar el listener si este no esta siendo usado. Por ejemplo onDestroy().

5. Conclusion Parcial

El account manager es muy util para tener todas las cuentas centralizadas en un solo lugar, pero esto tiene sus inconvenientes.

No hay comentarios:

Publicar un comentario