首页 > 解决方案 > 如何在特定钥匙串访问组中保存/获取访问令牌

问题描述

如何将 JSON Web 令牌保存到特定的钥匙串访问组,以及如何使用 Objective-c 从钥匙串中检索此令牌?(我想在不使用任何钥匙串包装器的情况下做到这一点。)

标签: iosobjective-c

解决方案


您确实可以使用 Apple 提供的 C API 在钥匙串中存储/​​检索/删除值。但首先,我想澄清您已经收到的答案:完全不鼓励将 JWT 存储在用户默认值中,因为存储在那里的任何内容都被视为纯文本并危及您的数据/API 安全性。

如果我没记错的话,您可以通过 FileManager 访问应用程序包并找到preferences.plist 来自行验证这一点。

现在,回到您的问题,我可以提供一些帮助,但我缺少访问特定钥匙串访问组的部分,虽然不应该很复杂......

因此,此步骤总结了钥匙串的一般用途:

  • 由于钥匙串是 SQLite3 数据库,因此您需要从创建查询开始。
  • 当您在其中存储内容时不会检查重复项,因此您需要先删除当前项目,然后再添加新项目以保持内容到位,如果您尝试删除的项目不存在,则它什么也不做。
  • 将项目(查询)添加到钥匙串。

这是 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 的类型。

希望您可以以此为指导,我敢打赌,您需要向查询添加一个额外的值,以便使用您要从中获取数据的特定钥匙串组。


推荐阅读