【问题标题】:Decoding JSON Web Tokens in Swift在 Swift 中解码 JSON Web 令牌
【发布时间】:2015-05-23 01:06:48
【问题描述】:

尝试在 Swift 中解码 JWT 有效负载并且遇到了非常困难的时间

static func decodePayload(tokenstr: String) {

    //splitting JWT to extract payload
    let arr = split(tokenstr) {$0 == "."}

    //base64 encoded string i want to decode
    let base64String = arr[1] as String
    println(base64String) //eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0

    //attempting to convert base64 string to nsdata 
    let nsdata: NSData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))

    //decoding fails because nsdata unwraps as nil
    let base64Decoded: NSString = NSString(data: nsdata!, encoding: NSUTF8StringEncoding)!


}

【问题讨论】:

    标签: ios swift base64 jwt


    【解决方案1】:
    eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0
    

    不是有效的 Base64 编码字符串,因为它的长度 不是 4 的倍数。一些 Base64 解码器可以容忍这个错误,但是 NSData 方法没有。

    所以这实际上是服务器端创建的错误 Base64 编码的字符串。如有必要,您可以在您的应用程序中修复它 通过使用 = 字符添加所需的填充(针对 Swift 2 更新的代码):

    var base64String = arr[1] as String
    if base64String.characters.count % 4 != 0 {
        let padlen = 4 - base64String.characters.count % 4
        base64String += String(count: padlen, repeatedValue: Character("="))
    }
    

    现在解码按预期工作:

    if let data = NSData(base64EncodedString: base64String, options: []),
        let str = String(data: data, encoding: NSUTF8StringEncoding) {
        print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
    }
    

    斯威夫特 4:

    var base64String = "eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0"
    
    if base64String.count % 4 != 0 {
        let padlen = 4 - base64String.count % 4
        base64String.append(contentsOf: repeatElement("=", count: padlen))
    }
    
    if let data = Data(base64Encoded: base64String) ,
        let str = String(data: data, encoding: .utf8) {
        print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
    }
    

    【讨论】:

    • 最佳实践应该将 jwt 令牌存储在哪里?我一直在想它应该与用户名和密码一起存储到钥匙串中。
    • @user805981:我实际上对 jwt 令牌一无所知。但是,是的,密码等敏感数据应该存储在钥匙串中。
    • 谢谢。关于钥匙扣。每个应用程序的钥匙串可以存储多少个钥匙串字典?每个应用程序是无限的还是一个密码钥匙串?
    【解决方案2】:

    以上解决方案对我有用,我已转换为 swift3

    这里可以找到swift3代码

    var base64Str = arr[1] as String
    if base64Str.characters.count % 4 != 0 {
        let padlen = 4 - base64Str.characters.count % 4      
        base64Str += String(repeating: "=", count: padlen)
    }
    
    if let data = Data(base64Encoded: base64Str, options: []),
        let str = String(data: data, encoding: String.Encoding.utf8) {
            print(str)
    }
    

    【讨论】:

      【解决方案3】:

      Swift 4 如下:

      if let data = Data(base64Encoded: base64String, options: []),
              let str = String(data: data as Data, encoding: String.Encoding.utf8) {
              print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
          }
      

      【讨论】:

      • 在 Swift 4 中,使用 Data 比使用 NSData 更好(使用 Data 比将 NSData 转换为 Data 更好)。 无论如何,@raju-abe 在他们的回答中已经给出了 Swift 3+ 的更新。请不要发布重复/不完整的内容。
      猜你喜欢
      • 2017-04-16
      • 2016-07-28
      • 2019-03-23
      • 2016-12-20
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多