| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- import CryptoKit
- import Foundation
- enum ZoomMeetingSDKJWTError: Error {
- case invalidUTF8
- case jsonSerializationFailed
- }
- /// Builds a [Meeting SDK JWT](https://developers.zoom.us/docs/meeting-sdk/auth/) from the OAuth client id/secret
- /// (same credentials as the in-app Zoom OAuth app when Meeting SDK is enabled on that app).
- enum ZoomMeetingSDKJWT {
- static func makeMeetingSDKToken(clientId: String, clientSecret: String) throws -> String {
- let header: [String: String] = ["alg": "HS256", "typ": "JWT"]
- let iat = Int(Date().timeIntervalSince1970) - 30
- let exp = iat + 60 * 60 * 2
- let payload: [String: Any] = [
- "appKey": clientId,
- "iat": iat,
- "exp": exp,
- "tokenExp": exp
- ]
- guard let headerData = try? JSONSerialization.data(withJSONObject: header, options: [.sortedKeys]),
- let payloadData = try? JSONSerialization.data(withJSONObject: payload, options: [.sortedKeys]),
- let headerString = String(data: headerData, encoding: .utf8),
- let payloadString = String(data: payloadData, encoding: .utf8) else {
- throw ZoomMeetingSDKJWTError.jsonSerializationFailed
- }
- let headerPart = base64URLEncode(headerString.data(using: .utf8) ?? Data())
- let payloadPart = base64URLEncode(payloadString.data(using: .utf8) ?? Data())
- let signingInput = "\(headerPart).\(payloadPart)"
- guard let signingData = signingInput.data(using: .utf8) else {
- throw ZoomMeetingSDKJWTError.invalidUTF8
- }
- let key = SymmetricKey(data: Data(clientSecret.utf8))
- let mac = HMAC<SHA256>.authenticationCode(for: signingData, using: key)
- let signaturePart = base64URLEncode(Data(mac))
- return "\(signingInput).\(signaturePart)"
- }
- private static func base64URLEncode(_ data: Data) -> String {
- data.base64EncodedString()
- .replacingOccurrences(of: "+", with: "-")
- .replacingOccurrences(of: "/", with: "_")
- .replacingOccurrences(of: "=", with: "")
- }
- }
|