如何将JSON Web令牌保存到特定的钥匙串访问组,以及如何使用Objective-c从钥匙串中检索此令牌? (我想不使用任何钥匙扣包装器就可以做到这一点。)
答案 0 :(得分:0)
您确实可以使用Apple提供的C API在钥匙串中存储/检索/删除值。我想澄清一下您已经收到的答案:完全不建议将JWT存储在“用户默认值”中,因为存储在其中的任何内容都被视为纯文本,并损害了数据/ API的安全性。您可以通过FileManager访问该应用程序的捆绑包并在没有问题的情况下找到preferences.plist来进行验证。
现在,回到您的问题,我可以提供一些帮助,但是我缺少访问特定钥匙串访问组的部分,尽管应该不复杂...
因此,此步骤总结了钥匙串的一般用法:
这里是Swift中的一个示例,请理解它,以便您可以轻松地将其翻译为ObjC:
// value is anything you want to store, let's say "Hello Jobs", and you need to
convert that value to data.
if let valueData = value.data(using: .utf8) {
return [kSecClass as String: kSecClassGenericPassword as String,
kSecAttrAccount as String: key,
kSecValueData as String: valueData] as [String:Any]
}
SecItemDelete(query as CFDictionary) // Delete the query if exists
SecItemAdd(query as CFDictionary, nil) // Store your value
如您所见,您需要将查询强制转换为CFDictionary,因为这就是C API作为参数接收的预期类型。
现在要检索存储的值,您需要执行以下操作:
// You need a query again, but this time you add extra parameters to indicate you want to return the value as data using the boolean below and to limit the query to just 1 item.
let query = [kSecClass as String: kSecClassGenericPassword as String,
kSecAttrAccount as String: key,
kSecReturnData as String: kCFBooleanTrue,
kSecMatchLimit as String: kSecMatchLimitOne] as [String: Any]
// You define a var to use its reference (memory address) as its required by the SecItemCopyMatching API so it can store the outcome of the query there.
var dataTypeRef: AnyObject?
let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == noErr {
return dataTypeRef as? Data // If the query was successful you retrieve the data by casting your previously defined var to a Data type
}
这里唯一要做的就是将检索到的Data值转换为所需的值,在这种情况下,它将是一个String,因为这就是JWT的类型。
希望您可以以此为指导,我敢打赌,您需要为查询添加一个额外的值,才能使用您要从中获取数据的特定钥匙串组。
答案 1 :(得分:0)
要将令牌保存到特定的钥匙串访问组,首先需要在Apple Developer控制台中创建与您的应用程序ID关联的钥匙串访问组。然后,为您的应用程序ID授予访问该访问组的权利。这应该给您一个如下所示的权利文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>keychain-access-groups</key>
<array>
<string>656CMN2Q97.com.mycompany.myapp</string>
</array>
</dict>
</plist>
然后,对其进行读写就这么简单:
NSString *kapiToken = @"apiToken";
NSString *kServices = @"Services";
self.apiToken = [UICKeyChainStore stringForKey:kapiToken service:kServices];
....
[UICKeyChainStore setString:self.apiToken forKey:kapiToken service:kServices];
答案 2 :(得分:-1)
就我所能提供的帮助来说,如果没有钥匙串包装器,您将无法访问钥匙串商店。为了安全起见,Apple没有打开没有Keychain包装器的API来访问Keychain商店。希望这会有所帮助。
您可以将令牌存储在 Singleton 类中,因为我认为该令牌将在每次应用重新启动时刷新。如果不是这种情况,还可以将其存储在NSUserDefaults中。