2011-12-19 11 views
15

Utilizzo AFNetworking come livello di rete per la mia app iPhone che si collega a un server Rails che utilizza Devise per l'autenticazione. Se eseguo l'accesso (con una chiamata POST) fornendo nome utente/password, dopo di che qualsiasi GET che eseguo è ok.AFNetworking e cookie

Se chiudo l'app (non solo in background) tutte le richieste GET falliscono perché suppongo che non siano autenticate.

Quindi presumo che i cookie siano memorizzati da qualche parte; c'è un modo per salvarli in NSUserDefaults o in un posto del genere al fine di evitare il log in tutto il tempo?

risposta

9

I cookie vengono infatti automaticamente archiviati per tutta la durata dell'applicazione per eventuali richieste successive su un determinato server. Una buona strategia potrebbe essere quella di memorizzare il nome utente e la password nel portachiavi o in NSUserDefaults come questo:

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

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

Si consiglia di utilizzare questo in combinazione con AFHTTPClient per inviare le credenziali insieme a ogni richiesta in un'intestazione Authorization HTTP .

+1

Grazie per la risposta, sì, questo è quello che faccio per mantenere le vecchie credenziali. Quello che vorrei evitare è il POST iniziale per l'accesso ad ogni riavvio dell'app, mi chiedevo solo se la durata del cookie gestito da AFNetworking può essere estesa. –

+26

In realtà, per favore non memorizzare nomi utente e password in NSUserDefaults. Usa invece il portachiavi. Apple distribuisce un KeychainWrapper che fa sostanzialmente la stessa cosa, ma in modo più sicuro. – eddieroger

75

Non è necessario preoccuparsi di NSUserDefaults né di alcun wrapper portachiavi se si utilizza NSURLCredential. Infatti è molto più semplice da usare, in quanto consente di memorizzare sia nome utente che password nel portachiavi in due righe di codice.

Il tuo codice sarebbe qualcosa di simile che una volta che l'utente è connesso:

NSURLCredential *credential; 

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

Poi, ogni volta che viene lanciata l'applicazione, è possibile verificare se l'utente è già stato effettuato l'accesso per la ricerca di qualsiasi credenziale in per accedere automaticamente indietro il vostro utente (se necessario):

NSURLCredential *credential; 
NSDictionary *credentials; 

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

È inoltre necessario pulire le credenziali quando l'utente vuole disconnettersi:

NSURLCredential *credential; 
NSDictionary *credentials; 

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

loginProtectionSpace viene creato una volta per tutte. Si noti che questo codice di esempio presuppone che ci sia solo una credenziale in questo spazio, che di solito è il caso, a meno che non si gestiscano più account.

Ecco un esempio di come si dovrebbe creare 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

Dov'è il codice per creare un NSURLProtectionSpace? Ho guardato i documenti Apple, ma non mi è chiaro come crearne uno. Mi riferisco a "self.loginProtectionSpace" – user798719

+0

Immagino che cosa intendo dire, fanno la questione port e hostname o sono questi namespace? – user798719

+4

Ho aggiornato la mia risposta con un esempio di come creare un NSURLProtectionSpace. Sostituire l'URL con il proprio e aggiornare il parametro del metodo di autenticazione con il metodo di autenticazione utilizzato dal proprio server. – Phil