2011-12-19 10 views
15

Estoy utilizando AFNetworking como capa de red para mi aplicación de iPhone que se conecta a un servidor de Rails que usa Devise para la autenticación. Si inicio sesión (con una llamada POST) proporcionando nombre de usuario/contraseña, luego de eso, cualquier GET que realice estará bien.AFNetworking and Cookies

Si cierro la aplicación (no solo el fondo), todas mis solicitudes GET fallan porque supongo que no están autenticadas.

Supongo que las cookies se almacenan en algún lugar; ¿Hay alguna manera de guardarlos en NSUserDefaults o en algún lugar así para evitar el inicio de sesión todo el tiempo?

Respuesta

9

Las cookies se almacenan automáticamente durante el tiempo de vida de su aplicación para cualquier solicitud posterior en un servidor en particular. Una buena estrategia sería la de almacenar el nombre de usuario y contraseña en el llavero o en NSUserDefaults así:

// Setting 
[[NSUserDefaults standardDefaults] setObject:username forKey:@"username"]; 
[[NSUserDefaults standardDefaults] synchronize]; 

// Getting 
NSString *username = [[NSUserDefaults standardDefaults] objectForKey:@"username"]; 

Es posible que desee utilizar esto en combinación con AFHTTPClient para enviar sus credenciales junto con cada petición en una cabecera Authorization HTTP .

+1

gracias por responder, sí, esto es lo que hago para mantener las credenciales de edad. Lo que me gustaría evitar es el POST inicial para iniciar sesión en cada reinicio de la aplicación, me preguntaba si la vida útil de la cookie manejada por AFNetworking puede extenderse. –

+26

En realidad, no almacene nombres de usuario y contraseñas en NSUserDefaults. Use el llavero en su lugar. Apple distribuye un KeychainWrapper que básicamente hace lo mismo, pero de forma más segura. – eddieroger

75

No necesita molestarse con NSUserDefaults ni ningún envoltorio de llavero si usa NSURLCredential. De hecho NSURLCredential es mucho más simple de usar, ya que le permite almacenar nombre de usuario y contraseña en el llavero en dos líneas de código.

Su código sería algo así como que una vez que el usuario se registra en:

NSURLCredential *credential; 

credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent]; 
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace]; 

Entonces, cada vez que se inicia la aplicación, se puede comprobar si el usuario ya se ha iniciado sesión mediante la búsqueda de cualquier credencial para conectarse automáticamente a su usuario (si es necesario):

NSURLCredential *credential; 
NSDictionary *credentials; 

credentials = [[NSURLCredentialStorage sharedCredentialStorage] credentialsForProtectionSpace:self.loginProtectionSpace]; 
credential = [credentials.objectEnumerator nextObject]; 
NSLog(@"User %@ already connected with password %@", credential.user, credential.password); 

también es necesario limpiar la credencial cuando el usuario desea cerrar la sesión:

NSURLCredential *credential; 
NSDictionary *credentials; 

credentials = [[NSURLCredentialStorage sharedCredentialStorage] credentialsForProtectionSpace:self.loginProtectionSpace]; 
credential = [credentials.objectEnumerator nextObject]; 
[[NSURLCredentialStorage sharedCredentialStorage] removeCredential:credential forProtectionSpace:self.loginProtectionSpace]; 

loginProtectionSpace se crea de una vez por todas. Tenga en cuenta que este código de ejemplo supone que solo hay una credencial en este espacio, que generalmente es el caso a menos que administre varias cuentas.

Aquí es un ejemplo de cómo se crearía un NSURLProtectionSpace:

NSURL *url = [NSURL URLWithString:@"http://www.example.com"]; 
self.loginProtectionSpace = [[NSURLProtectionSpace alloc] initWithHost:url.host 
                    port:[url.port integerValue] 
                   protocol:url.scheme 
                   realm:nil 
                authenticationMethod:NSURLAuthenticationMethodHTTPDigest]; 
+0

¿Dónde está el código para crear un NSURLProtectionSpace? Miré los documentos de Apple pero no tengo muy claro cómo crearlos. Me refiero a "self.loginProtectionSpace" – user798719

+0

Supongo que lo que quiero decir es, ¿importa el puerto y el nombre de host o estos espacios de nombres? – user798719

+4

He actualizado mi respuesta con un ejemplo de cómo crear un NSURLProtectionSpace. Reemplace la URL por la suya y actualice el parámetro del método de autenticación con el método de autenticación utilizado por su servidor. – Phil

Cuestiones relacionadas