Xero-API和Vapor 3无法连接到接收令牌。

问题描述 投票:3回答:1

我有一個vapor3應用程式,我試圖連接到Xero Api,過程相當簡單。我们向用户发送一个xero网页,让他们登录并授权我们的连接,然后重定向到我的vapor3应用。在应用程序中,我们使用重定向中提供的代码连接到xero服务器,然后xero会发出一个访问令牌,以便继续使用。这个过程描述如下 此处

问题是我无法连接到xero获得访问令牌。我尝试了2种方法,第一种是使用HTTPClient,使用这段代码。

 let m = try decoder.decode(Master.self, from: masterDoc!)
 let ci = m.xeroAppKey.data(using: .utf8)?.base64EncodedString() //convert from string to base encoded
 let xs = m.xeroAppSec.data(using: .utf8)?.base64EncodedString() //convert from string to base encoded
 let authorization = "Basic " + ci! + ":" + xs!
 print("authorisation is \(authorization)")
 return HTTPClient.connect(hostname: "identity.xero.com", on: req).flatMap{client in
       var httpReq = HTTPRequest(method: .POST, url: "https://identity.xero.com/connect/token")
       httpReq.headers.add(name: "authorization", value: authorization)
       httpReq.headers.add(name: "Content-Type", value: "x-www-form-urlencoded")
       httpReq.body = HTTPBody(string: "grant_type=authorization_code&code=\(code)&redirect_uri=http://localhost:8080/XeroAuthRedirect")

       return client.send(httpReq).flatMap{resp in
         print("response is \(resp) with status \(resp.status)")
         return req.future().map{
           return .ok
         }  
      }
    } 

这样我得到了以下的响应:

HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: https://identity.xero.com/connect/token
Expires: Tue, 02 Jun 2020 07:59:59 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Tue, 02 Jun 2020 07:59:59 GMT
Connection: keep-alive

这表明终端已经移动了 但建议的位置和我要连接的位置是一样的。我在文档中找不到任何地方表明端点已经改变。HTTPClient似乎也不遵循重定向。

所以我试着用URLSession连接,而不是用这个代码。

let url = URL(string:"https://identity.xero.com/connect/token")!
                let payload = "grant_type=authorization_code&code=\(code)&redirect_uri=http://localhost:8080/XeroAuthRedirect".data(using: .utf8)

                let promise = req.eventLoop.newPromise(HTTPStatus.self)

                var request = URLRequest(url: url)
                request.httpMethod = "POST"
                request.addValue(authorization, forHTTPHeaderField: "authorization")
                request.addValue("x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
                request.httpBody = payload

                URLSession.shared.dataTask(with: request) {(data, response, error) in

                    if let error = error {
                        print(error.localizedDescription)
                        promise.fail(error: error) // (!)
                        return
                    }

                    guard let data = data else {
                        print("empty data")
                        promise.fail(error: SumUpError.invalidResponse) // (!)
                        return
                    }

                    guard let str = String(data: data, encoding: .utf8) else {
                        print("invalid data")
                        promise.fail(error: SumUpError.invalidResponse) // (!)
                        return
                    }

                    print(str)


                    print("response is \(String(describing: response))")


                }.resume()

我得到以下错误信息。

{"error":"invalid_request"}

任何想法是怎么回事,或者我怎么能让这个连接运行起来,都是非常感激的。

swift vapor xero-api
1个回答
1
投票

好的,所以最后的答案是使用在req.client()找到的vapor客户端服务。

我用的是下面的代码。我还犯了一个菜鸟的错误,就是把客户端的id和客户端的secret编码后再梳理,而不是先凑齐再编码。文档中确实有这样的说明,但我想还不够清楚。总之这里是用Vapor 3连接到Xero Api的代码。


    let toBase = "\(clientId):\(clientSecret)".data(using: .utf8)?.base64EncodedString()
    let authorization = "Basic " + toBase!           
    let payload = "grant_type=authorization_code&code=\(code)&redirect_uri=http://localhost:8080/XeroAuthRedirect".data(using: .utf8)!
    let request = Request( using: req)
    request.http.url = URL(string:"https://identity.xero.com/connect/token")!
    request.http.body = payload.convertToHTTPBody()
    request.http.method = HTTPMethod.POST
    request.http.headers.add(name: "authorization", value: authorization)
    request.http.headers.add(name: "Content-Type", value: "application/x-www-form-urlencoded")
 return try req.client().send(request).flatMap{resp in 

}

希望这对试图用Vapor添加xero的人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.