IOS: Как сохранить имя пользователя и пароль в приложении?

У меня есть экран входа в приложение iOS. Имя пользователя и пароль будут сохранены в NSUserDefaults и снова загружены на экран входа в систему при повторном входе в приложение (конечно, NSUserDefaults являются постоянными).

Теперь у пользователя есть возможность отключить функцию сохранения имени пользователя и пароля.

Таким образом, NSUserDefaults будут удалены.

Но в моем приложении мне нужно это имя пользователя/пароль для запросов к базе данных для пользователя. Итак: где хранить данные, кроме NSUserDefaults? (Это место может/должно быть удалено, когда пользователь покидает приложение или выходит из системы).

Ответ 1

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

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

Включите Security.framework(в Xcode 3 щелкните правой кнопкой мыши папку фреймворков и добавьте существующую инфраструктуру. В Xcode 4 выберите свой проект, затем выберите цель, перейдите на вкладку "Сборка фаз" и нажмите "+" в разделе "Связывание с файлами" ) и KeychainItemWrapper. h и .m в ваш проект, #import.h файл, где вам нужно использовать keychain, а затем создать экземпляр этого класса:

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

(YourAppLogin может быть любым, что вы выбрали для вызова вашего объекта Keychain, и при необходимости можете иметь несколько элементов)

Затем вы можете установить имя пользователя и пароль, используя:

[keychainItem setObject:@"password you are saving" forKey:kSecValueData];
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

Получить их используя:

NSString *password = [keychainItem objectForKey:kSecValueData];
NSString *username = [keychainItem objectForKey:kSecAttrAccount];

Или удалите их, используя:

[keychainItem resetKeychainItem];

Ответ 3

Очень простое решение через Брелки.

Это простая оболочка для системы Keychain. Просто добавьте файлы SSKeychain.h, SSKeychain.m, SSKeychainQuery.h и SSKeychainQuery.m в свой проект и добавьте Security.framework в вашу цель.

Чтобы сохранить пароль:

[SSKeychain setPassword:@"AnyPassword" forService:@"AnyService" account:@"AnyUser"]

Чтобы получить пароль:

NSString *password = [SSKeychain passwordForService:@"AnyService" account:@"AnyUser"];

Где setPassword - какое значение вы хотите сохранить, а forService - это какая переменная, которую вы хотите сохранить, а учетная запись - для какого пользователя/объекта используется пароль и любая другая информация.

Ответ 4

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

См. мой подробный ответ .

Ответ 5

Если у вас возникла проблема с получением пароля с помощью оболочки keychain, используйте этот код:

NSData *pass =[keychain objectForKey:(__bridge id)(kSecValueData)];
NSString *passworddecoded = [[NSString alloc] initWithData:pass
                                           encoding:NSUTF8StringEncoding];

Ответ 6

Я решил ответить, как использовать keychain в iOS 8 с использованием Obj-C и ARC.

1) Я использовал keychainItemWrapper (версию ARCifief) из GIST: https://gist.github.com/dhoerl/1170641/download - Добавьте (+ копию) KeychainItemWrapper.h и .m к вашему проекту

2) Добавьте инфраструктуру безопасности в свой проект (проверьте проект > Фазы сборки > Связать двоичный файл с библиотеками)

3) Добавьте библиотеку безопасности (#import) и KeychainItemWrapper (#import "KeychainItemWrapper.h" ) в файлы .h и .m, где вы хотите использовать keychain.

4) Чтобы сохранить данные в цепочке ключей:

NSString *emailAddress = self.txtEmail.text;
NSString *password = self.txtPasword.text;
//because keychain saves password as NSData object
NSData *pwdData = [password dataUsingEncoding:NSUTF8StringEncoding];

//Save item
self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[self.keychainItem setObject:emailAddress forKey:(__bridge id)(kSecAttrAccount)];
[self.keychainItem setObject:pwdData forKey:(__bridge id)(kSecValueData)];

5) Чтение данных (возможно, экран входа в систему при загрузке > viewDidLoad):

self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

self.txtEmail.text = [self.keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];

//because label uses NSString and password is NSData object, conversion necessary
NSData *pwdData = [self.keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSString *password = [[NSString alloc] initWithData:pwdData encoding:NSUTF8StringEncoding];
self.txtPassword.text = password;

Наслаждайтесь!

Ответ 7

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

Ответ 8

Я посмотрел на использование KeychainItemWrapper (версия ARC), но я не нашел его обертку Objective C как полезную по своему усмотрению.

Я использовал это решение Кишикава Кацуми, который означало, что я написал меньше кода и не должен был использовать приведения для хранения значений NSString.

Два примера хранения:

[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"];
[UICKeyChainStore setString:@"P455_w0rd$1$G$Z$" forKey:@"password"];

Два примера извлечения

UICKeyChainStore *store = [UICKeyChainStore keyChainStore];
    // or
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"YOUR_SERVICE"];

NSString *username = [store stringForKey:@"username"];
NSString *password = [store stringForKey:@"password"];

Ответ 9

попробуйте следующее:

 KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData]; 
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

может это помочь.

Ответ 10

В приведенном выше кодеке есть небольшая ошибка (кстати, Дэйв очень помог вам поблагодарить)

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

[self.keychainItem setObject:@"myCredentials" forKey:(__bridge id)(kSecAttrService)];

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

Ответ 11

Чтобы обновить этот вопрос:

Для тех, кто использует Swift checkout, это быстрое и быстрое внедрение Mihai Costea, поддерживающее группы доступа:

https://github.com/macostea/KeychainItemWrapper.swift/blob/master/KeychainItemWrapper.swift

Перед использованием брелка: рассмотрите два раза перед сохранением паролей. Во многих случаях достаточно хранить токен аутентификации (например, идентификатор сеанса persistence) и имя электронной почты или учетной записи. Вы можете легко аннулировать токены аутентификации для блокировки несанкционированного доступа, требуя от пользователя повторного входа в систему на зараженном устройстве, но не требующего пароля reset и необходимости повторного входа на все устройства (мы не только используем Apple, мы?).

Ответ 12

Следующее должно работать нормально:

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData]; 
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

Ответ 13

Но теперь вы можете использовать NURLCredential вместо оболочки keychain. Он делает то, что нам нужно.