【问题标题】:Adding other variables into keychain将其他变量添加到钥匙串中
【发布时间】:2023-05-29 06:47:01
【问题描述】:

我目前正在为我的 iOS 应用程序使用此版本的 KeyChain Wrapper。但是,我在添加其他变量时遇到了困难。

我希望能够将以下值添加到我的钥匙串中:

  • 用户名
  • 密码
  • 访问令牌
  • 刷新令牌

目前我正在做这样的事情:

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"com.myname.myapp" accessGroup:nil];
[keychainItem setObject:usernameField.text forKey:(__bridge id)(kSecAttrAccount)];
[keychainItem setObject:password1Field.text forKey:(__bridge id)(kSecValueData)];

我尝试将多个对象设置为 kSecValueData,但它只是覆盖了之前设置的对象。

 [keychainItem setObject:password1Field.text forKey:(__bridge id)(kSecValueData)];
 [keychainItem setObject:access_token forKey:(__bridge id)(kSecValueData)];
 [keychainItem setObject:access_token forKey:(__bridge id)(kSecValueData)];

所以我想知道是否有人知道我应该怎么做...我应该将我的initWithIdentifier 更改为@"com.myname.myapp.accesstoken" 之类的东西吗?还有其他人有更好的方法吗?我不知道initWithIdentifieraccessGroup 是如何工作的。

【问题讨论】:

    标签: ios security access-token keychain


    【解决方案1】:

    所以我创建了一个变通方案,但我确信有更好的解决方案。

    我创建了一个将 NSDictionary 转换为 JSON 字符串的方法,并将 JSON 字符串插入到钥匙串密码中,这样您就可以安全地存储多个值。

    NSDictionary *secretValues = [[NSDictionary alloc] initWithObjectsAndKeys:
                                   password, @"password",
                                   access_token, @"access_token",
                                   refresh_token, @"refresh_token", nil];
    
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:secretValues
                                                       options:0
                                                         error:&error];
    
    
    if (! jsonData) {
        NSLog(@"Got an error: %@", error);
    } else {
        NSString *jsonString = [[NSString alloc] initWithData:jsonData 
                                                     encoding:NSUTF8StringEncoding];
        [keychainItem setObject:jsonString forKey:(__bridge id)(kSecValueData)];
    }
    

    如果你想得到密码,你可以这样做:

    - (NSString *) getPassword{
    
        KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"com.myname.app" accessGroup:nil];
    
        NSString *password = [[NSString alloc] initWithData:[keychainItem objectForKey:(__bridge id)(kSecValueData)]
                                                   encoding:NSUTF8StringEncoding];
    
        NSDictionary *jsonData =
        [NSJSONSerialization JSONObjectWithData: [password dataUsingEncoding:NSUTF8StringEncoding]
                                        options: NSJSONReadingMutableContainers
                                          error: nil];
    
        return jsonData[@"password"];
    }
    

    我确信存在更好的方法,但这是我能想到的最好方法。

    【讨论】:

    • +1 好答案。这将存储行为类似于 JSON 对象的对象,例如字典或数组……这很好。我目前正在寻找最佳解决方案,如果找到此帖子:*.com/a/20649567/4018041。如果你想维护对象的数据类型,你应该使用 NSPropertyListSerialization。