Skip to content

Instantly share code, notes, and snippets.

@Lavmint
Created September 3, 2019 16:08
Show Gist options
  • Save Lavmint/a271df72aba21da2a8ff58b1b0fdf6dc to your computer and use it in GitHub Desktop.
Save Lavmint/a271df72aba21da2a8ff58b1b0fdf6dc to your computer and use it in GitHub Desktop.
JWT Swift5 + Common Crypto
import Foundation
import CommonCrypto
public func jwt(payload: [String: Any], secret: String) -> String? {
guard let data = try? JSONSerialization.data(withJSONObject: payload, options: []) else {
return nil
}
return jwt(payload: data, secret: secret)
}
public func jwt(payload: Data, secret: String) -> String? {
guard let str = String(data: payload, encoding: .utf8) else {
return nil
}
return jwt(payload: str, secret: secret)
}
public func jwt<T: Encodable>(payload: T, secret: String) -> String? {
guard let data = try? JSONEncoder().encode(payload) else {
return nil
}
return jwt(payload: data, secret: secret)
}
public func jwt(payload: String, secret: String) -> String? {
guard let payload64String = payload.data(using: .utf8)?.base64EncodedString() else {
return nil
}
let headers = """
{"alg":"HS256","typ":"JWT"}
"""
guard let headers64String = headers.data(using: .utf8)?.base64EncodedString() else {
return nil
}
var jwt = "\(headers64String).\(payload64String)"
guard let signature = jwt.hmac256(secret: secret) else {
return nil
}
jwt += ".\(signature)"
return jwt
}
private extension String {
func hmac256(secret: String) -> String? {
guard let dataCharPtr = self.base64URL.cString(using: .utf8) else { return nil }
guard let keyCharPtr = secret.cString(using: .utf8) else { return nil }
var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
CCHmac(
CCHmacAlgorithm(kCCHmacAlgSHA256),
keyCharPtr,
strlen(keyCharPtr),
dataCharPtr,
strlen(dataCharPtr),
&digest
)
return Data(digest).base64EncodedString().base64URL
}
/// https://en.wikipedia.org/wiki/Base64#Variants_summary_table
var base64URL: String {
return self
.replacingOccurrences(of: "=", with: "")
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment