移动端有三个实现方案,第一个是用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 {
# 错误处理
}
网友评论