Аутентификация с помощью Cloud Firestore rest api - PullRequest
0 голосов
/ 12 декабря 2018

Привет, я пытаюсь пройти аутентификацию в 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.но я получаю ту же ошибку, любой, кто хочет ее проверить, должен сначала попробовать Почтальон.Я прилагаю запрос почтальона.

Коллекция почтальона

...