AFNetworking и Cookies

Я использую AFNetworking в качестве сетевого уровня для моего приложения для iPhone, которое подключается к серверу Rails, который использует Devise для аутентификации. Если я вхожу (с помощью POST-вызова), предоставляя имя пользователя / пароль, то после этого любой GET, который я выполняю, в порядке.

Если я закрою приложение (не только фон), то все мои GET-запросы не будут выполнены, потому что я предполагаю, что они не аутентифицированы.

Поэтому я предполагаю, что куки хранятся где-то; есть ли способ сохранить их в NSUserDefaults или где-то так, чтобы не входить в систему постоянно?

2 ответа

Решение

Куки действительно автоматически сохраняются в течение всего срока действия вашего приложения для любых последующих запросов на конкретном сервере. Хорошей стратегией будет сохранение имени пользователя и пароля в цепочке для ключей или в NSUserDefaults как это:

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

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

Вы можете использовать это в сочетании с AFHTTPClient отправлять свои учетные данные вместе с каждым запросом в Authorization HTTP заголовок.

Вам не нужно беспокоиться ни о NSUserDefaults, ни о какой-либо оболочке для ключей, если вы используете NSURLCredential, В самом деле NSURLCredential намного проще в использовании, так как позволяет хранить имя пользователя и пароль в цепочке для ключей в две строки кода.

Ваш код будет выглядеть примерно так, как только пользователь войдет в систему:

NSURLCredential *credential;

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

Затем, каждый раз, когда приложение запускается, вы можете проверить, вошел ли ваш пользователь в систему, выполнив поиск каких-либо учетных данных для автоматического повторного входа пользователя (если это необходимо):

NSURLCredential *credential;
NSDictionary *credentials;

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

Вам также необходимо очистить учетные данные, когда пользователь хочет выйти из системы:

NSURLCredential *credential;
NSDictionary *credentials;

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

loginProtectionSpace создается раз и навсегда. Обратите внимание, что в этом примере кода предполагается, что в этом месте есть только одна учетная запись, что обычно имеет место, если вы не управляете несколькими учетными записями.

Вот пример того, как вы могли бы создать 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];
Другие вопросы по тегам