AFNetworking и Cookies
Я использую AFNetworking в качестве сетевого уровня для своего iPhone-приложения, которое подключается к серверу Rails, который использует Devise для аутентификации. Если я вхожу в систему (с вызовом POST), предоставляя имя пользователя/пароль, то после этого любой GET, который я выполняю, в порядке.
Если я закрою приложение (а не только фон), то все мои запросы GET завершатся неудачно, потому что я предполагаю, что они не аутентифицированы.
Поэтому я предполагаю, что файлы cookie хранятся где-то; есть ли способ сохранить их в NSUserDefaults
или где-то в этом роде, чтобы избежать регистрации во все время?
Ответы
Ответ 1
Файлы cookie действительно автоматически сохраняются в течение всего срока службы вашего приложения для любых последующих запросов на конкретном сервере. Хорошей стратегией было бы сохранить имя пользователя и пароль в цепочке ключей или в NSUserDefaults
следующим образом:
// Setting
[[NSUserDefaults standardDefaults] setObject:username forKey:@"username"];
[[NSUserDefaults standardDefaults] synchronize];
// Getting
NSString *username = [[NSUserDefaults standardDefaults] objectForKey:@"username"];
Вы можете использовать это в сочетании с AFHTTPClient
для отправки ваших учетных данных вместе с каждым запросом в заголовке HTTP Authorization
.
Ответ 2
Вам не нужно беспокоиться о 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];