iOS下JWT SH256算法生成Token

2021-02-08  本文已影响0人  ollieli

移动端有三个实现方案,第一个是用JWT官方库(它封装了实现方法,直接调用api就能得到token),第二个代码实现token,第三个是注入一段js脚本。后面两个方法还是要基于jwt算法,因为苹果没有直接提供RSA,HMAC算法。

首先JWT官方是提供了两个库:JWT和SwiftyJWT分别对应了OC和swift版本,但是出于某些原因我没试成功,所以各位如果官方提供的库能实现的话就不用自己写了。
我用的是代码实现,这里我用了SwiftyCrypto(SwiftyCrypto包含了所需要的HMAC算法,比JWT轻,所以我只取自己需要的,而且这个库是官方SwiftyJWT的作者写的,所以尽管大胆放心的用)。

话不多说上代码:

pod 'SwiftyCrypto'

完事了导入frameworks(下面两个都要):

import SwiftyCrypto
import CCommonCrypto

下一步是实现过程:

let headers = [
    "alg": "HS256", #你想要的算法
    "typ": "JWT", #固定的JWT
]
# 这边payload需要传些参数,必传的参数我就不说明了,官方都有解释(比如说iss表示issuer)
# 我想说payload里面是可以随便携带参数的,所以和后端商量好想带啥带啥。
let payload: NSDictionary = [
    #谁创建的,负责对这个token进行签名的issuer
    "iss": authClient,
    # issuer at创建时间,传秒数,用Int包一下是去除小数位,别忘了
    "iat": Int(Date().timeIntervalSince1970), 
    # JWT ID,随机32位字符串
    "jti": UUID().uuidString,
    # operation这个是自定义的携带参数
    "operation": "customer_login",
    "store_hash": storeHash, #自定义
    "customer_id": bigCommerceCustomerId, #自定义
]
# 说一下为什么要用ABC表示参数,JWT是用A.B.C表示
# 这样可以清楚他们之间的关系(实际上我完全是图省事:D)
do {
    let dataA = try JSONSerialization.data(withJSONObject: headers, options: [])
    let dataB = try JSONSerialization.data(withJSONObject: payload, options: [])
    let strA = dataA.base64EncodedString()
        .replacingOccurrences(of: "+", with: "-")
        .replacingOccurrences(of: "/", with: "_")
        .replacingOccurrences(of: "=", with: "")
    let strB = dataB.base64EncodedString()
        .replacingOccurrences(of: "+", with: "-")
        .replacingOccurrences(of: "/", with: "_")
        .replacingOccurrences(of: "=", with: "")
    let strAB = "\(strA).\(strB)"
    # dataS使用`secrect`整出来的
    guard let dataAB = strAB.data(using: String.Encoding.utf8, allowLossyConversion: false),
          let dataS = authClientSecret.data(using: String.Encoding.utf8, allowLossyConversion: false) else {
        # 这边有可能转换失败,记得错误处理
        return
    }
    # 下面这一坨也不知道啥意思,整就完事儿了
    # 感兴趣的可以百度一下HMAC算法
    let ctx = UnsafeMutablePointer<CCHmacContext>.allocate(capacity: 1)
    defer { ctx.deallocate() }
    dataS.withUnsafeBytes { buffer in
        # 瞅见没,我们的算法类型在这儿传入
        CCHmacInit(ctx, CCHmacAlgorithm(kCCHmacAlgSHA256), buffer, size_t(dataS.count)) 
    }
    dataAB.withUnsafeBytes { buffer in
        CCHmacUpdate(ctx, buffer, size_t(dataAB.count))
    }
    var hmac = Array<UInt8>(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
    CCHmacFinal(ctx, &hmac)
    let strHmac = Data(hmac).base64EncodedString()
        .replacingOccurrences(of: "+", with: "-")
        .replacingOccurrences(of: "/", with: "_")
        .replacingOccurrences(of: "=", with: "")
    # A + B + secrect = C的流程一波下来我想你也懂了哈哈
    let token = "\(strAB).\(strHmac)"
    
} catch let err {
    # 错误处理
}
参考:

JTW官方SDK各语言都有 https://jwt.io/#libraries-io
SwiftyCrypto

上一篇 下一篇

猜你喜欢

热点阅读