Привет, я пытаюсь пройти аутентификацию в Cloud Firestore rest Api.Я застрял, я не знаю, что я делаю не так здесь.Я работаю над приложением tvOS с Swift 4.2, я тоже пробовал это на Postman, но мне постоянно говорят:
{
"error": "invalid_grant",
"error_description": "Invalid JWT Signature."
}
Это мой код для создания токена JWT
let header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"
let scopes = "{\"iss\":\"MY_SERVICE_ACCOUNT_ID\",\"scope\":\"https://www.googleapis.com/auth/datastore\",\"aud\":\"https://www.googleapis.com/oauth2/v4/token\",\"exp\": \(NSNumber(integerLiteral: Int(Date().timeIntervalSince1970 + (60 * 20)))),\"iat\":\(NSNumber(integerLiteral: Int(Date().timeIntervalSince1970)))}"
print(scopes)
do {
let headerJWTBase64 = header.toBase64()
let ScopesJWTBase64 = scopes.toBase64()
let base64Msg = "\(headerJWTBase64).\(ScopesJWTBase64)"
let signedBase64 = base64Msg.hmac(algorithm: .SHA256, key: "MY_KEY")
let signedData = Data(base64Encoded: signedBase64)!
let signedSignature = self.base64UrlforData(data: signedData)
let jwt = "\(base64Msg).\(signedSignature)"
print(jwt)
let url = URL(string: "https://www.googleapis.com/oauth2/v4/token")!
NetworkHelper.executePostRequest(url: url, headers: [:], dict: ["grant_type=":"urn:ietf:params:oauth:grant-type:jwt-bearer","assertion":jwt], statusMatch: false)
.done{ json in
}.catch{ err in
}
} catch {
print("could not make data")
}
Это код для запроса сети.
class func executePostRequest(url :URL,
headers :[String:String],
dict :[String:Any],
statusMatch :Bool) -> Promise<[String : Any]> {
return Promise<[String : Any]> { promise in
var rq = URLRequest(url: url)
rq.httpMethod = "POST"
rq.allHTTPHeaderFields = headers
rq.httpBody = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
rq.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(.promise, with: rq).validate().then { (arg) -> Promise<[String:Any]> in
let (data, response) = arg
return getResponseFromData(ResponseObj: response, data: data, status: statusMatch)
}.done{ json in
promise.fulfill(json)
}.catch{err in
print(err.localizedDescription)
promise.reject(err)
}
}
}
Это расширение, которое я использую для шифрования SHA256
extension String {
enum CryptoAlgorithm {
case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
var HMACAlgorithm: CCHmacAlgorithm {
var result: Int = 0
switch self {
case .MD5: result = kCCHmacAlgMD5
case .SHA1: result = kCCHmacAlgSHA1
case .SHA224: result = kCCHmacAlgSHA224
case .SHA256: result = kCCHmacAlgSHA256
case .SHA384: result = kCCHmacAlgSHA384
case .SHA512: result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}
var digestLength: Int {
var result: Int32 = 0
switch self {
case .MD5: result = CC_MD5_DIGEST_LENGTH
case .SHA1: result = CC_SHA1_DIGEST_LENGTH
case .SHA224: result = CC_SHA224_DIGEST_LENGTH
case .SHA256: result = CC_SHA256_DIGEST_LENGTH
case .SHA384: result = CC_SHA384_DIGEST_LENGTH
case .SHA512: result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}
func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
let str = self.cString(using: String.Encoding.utf8)
let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = algorithm.digestLength
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
let keyStr = key.cString(using: String.Encoding.utf8)
let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
let digest = stringFromResult(result: result, length: digestLen)
result.deallocate()
return digest
}
func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
let hash = NSMutableString()
for i in 0..<length {
hash.appendFormat("%02x", result[i])
}
return String(hash)
}
func toBase64() -> String {
var str = Data(self.utf8).base64EncodedString()
str = str.replacingOccurrences(of: "=", with: "")
str = str.replacingOccurrences(of: "+", with: "-")
str = str.replacingOccurrences(of: "/", with: "_")
return Data(self.utf8).base64EncodedString()
}
}
Я также проверял это на Postman.но я получаю ту же ошибку, любой, кто хочет ее проверить, должен сначала попробовать Почтальон.Я прилагаю запрос почтальона.
Коллекция почтальона