iOS:如何在应用程序中存储用户名/密码?

我在iOS应用程序中有一个login屏幕。 用户名和密码将被保存在NSUserDefaults中,当你再次进入应用程序时(当然,NSUserDefaults是永久性的),将再次加载到login屏幕。

现在,用户有可能禁用用户名/密码保存function。

那么NSUserDefaults将被清除。

但在我的应用程序中,我需要用户名/密码进行数据库查询。 那么:除了NSUserDefaults之外,在哪里存储数据呢? (当用户退出应用程序或注销时,可以/应该删除此地点)。

您应该始终使用钥匙串存储用户名和密码,并且由于它安全地存储并且只能被您的应用程序访问,所以在应用程序退出时(如果您担心的话),不需要将其删除。

Apple提供了存储,读取和删除钥匙串项目的示例代码 ,以下是如何使用该示例中的钥匙串包装类,这大大简化了使用钥匙串。

包括Security.framework (在Xcode 3中,右键单击框架文件夹并添加现有的框架,在Xcode 4中select你的项目,然后select目标,进入Build Phases选项卡并点击Link Binary With Files)和KeychainItemWrapper .h&。 m文件导入到您的项目中,#导入.h文件,无论您需要使用钥匙串,然后创build此类的实例:

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

(您的应用程序login可以是任何你select调用你的钥匙项目,如果需要可以有多个项目)

然后您可以使用以下设置用户名和密码:

 [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]; 

如果你需要一个ARC版本的包装,这里是链接https://gist.github.com/1170641感谢;

通过钥匙链的一个非常简单的解决scheme。

这是系统钥匙串的简单包装。 只需将SSKeychain.hSSKeychain.mSSKeychainQuery.hSSKeychainQuery.m文件添加到您的项目并将Security.framework添加到您的目标。

保存密码:

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

取回密码:

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

其中setPassword是你想要保存的值, forService是你希望保存的variables,account是用户/对象的密码和其他信息。

你可以简单的使用NSURLCredential ,它只需要在两行代码中保存钥匙串中的用户名和密码

看到我的详细答案 。

如果您在使用钥匙串包装器检索密码时遇到问题,请使用以下代码:

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

我决定回答如何使用Obj-C和ARC在iOS 8中使用钥匙串。

1)我使用了GIST的keychainItemWrapper(ARCifief版本): https ://gist.github.com/dhoerl/1170641/download – 将KeychainItemWrapper.h和.m添加(+复制)到您的项目

2)将安全框架添加到您的项目中(签入项目>构build阶段>与库链接二进制文件)

3)将安全库(#import)和KeychainItemWrapper(#import“KeychainItemWrapper.h”)添加到要使用钥匙串的.h和.m文件中。

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)读取数据(可能login屏幕上加载> 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; 

请享用!

结帐这个示例代码,我试着先从示例代码的苹果包装,但这对我来说简单得多

我看着使用KeychainItemWrapper(ARC版本),但我没有find它的目标C包装作为健康所需。

我使用Kishikawa Katsumi的 这个解决scheme ,这意味着我写了更less的代码,并且不必使用强制转换来存储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"]; 

试试这个:

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

可能会有所帮助。

在上面的代码中有一个小错误(顺便说一下,Dave对你的post非常有帮助,谢谢)

在我们保存凭据的部分,为了正常工作,还需要下面的代码。

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

最有可能是因为我们第二次尝试(重新)使用相同的凭据login,发现它们已经分配到钥匙串项目和应用程序崩溃。 与上面的代码,它的作品就像一个魅力。

要更新这个问题:

对于那些使用Swift checkout的人来说,这个由Mihai Costea实现的快速实现支持访问组:

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

在使用钥匙串之前:在存储密码之前考虑两次。 在许多情况下,存储身份validation令牌(如持久性会话ID)和电子邮件或帐户名称可能就足够了。 您可以很容易地使身份validation令牌无效,以阻止未经授权的访问,要求用户再次login受感染的设备,但不需要重置密码,并且需要在所有设备上重新login(我们不只是使用苹果公司)。

以下应该工作得很好:

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

但是,现在你可以去NURLCredential而不是钥匙串包装。 它做我们需要做的事情。

对于swift,你可以使用这个库:

https://github.com/jrendel/SwiftKeychainWrapper

它支持所有版本的swift。