这里API OAUTH访问令牌请求 - Swift

发布于 2025-01-30 03:42:36 字数 3202 浏览 2 评论 0原文

我正在尝试从此处的API请求OAuth访问令牌。它正在工作,但是我正在收到间歇性错误。大约有50%的时间我会收到此回应:

{"errorId":"ERROR-8638f6e6-4fe9-420e-a31c-600f3062105b","httpStatus":401,"errorCode":401300,"message":"Signature mismatch. Authorization signature or client credential is wrong.","error":"invalid_client","error_description":"errorCode: '401300'. Signature mismatch. Authorization signature or client credential is wrong."}

这是我的代码:

    let url = URL(string: "https://account.api.here.com/oauth2/token")!
    
    //Credentials
    let accessKeyId = "xxxxxxxxxxxxxxxx"
    let accessKeySecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    
    //Base String
    let timeStamp = String(Int(Date().timeIntervalSince1970))
    let nonce = String(Int(Date().timeIntervalSince1970 * 1000))
    
    let grant_type = "grant_type=client_credentials"
    let oauth_consumer_key = "&oauth_consumer_key=" + accessKeyId
    let oauth_nonce = "&oauth_nonce=" + nonce
    let oauth_signature_method = "&oauth_signature_method=HMAC-SHA256"
    let oauth_timestamp = "&oauth_timestamp=" + timeStamp
    let oauth_version = "&oauth_version=1.0"
    
    let paramsString = grant_type + oauth_consumer_key + oauth_nonce + oauth_signature_method + oauth_timestamp + oauth_version
    let baseString = "POST&" + url.absoluteString.urlEncoded()! + "&" + paramsString.urlEncoded()!
    
    //Key
    let secret = accessKeySecret + "&"
    let key = SymmetricKey(data: Data(secret.utf8))
    
    //Signature
    let signature = HMAC<SHA256>.authenticationCode(for: Data(baseString.utf8), using: key)
    let baseEncodedSignature = Data(signature).base64EncodedString().urlEncoded()!
    
    //Request
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    //Request Headers
    let authString = "OAuth oauth_consumer_key=\"\(accessKeyId)\",oauth_nonce=\"\(nonce)\",oauth_signature=\"\(baseEncodedSignature)\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"\(timeStamp)\",oauth_version=\"1.0\""
    request.setValue(authString, forHTTPHeaderField: "Authorization")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
    
    //Request Body
    var requestBodyComponents = URLComponents()
    requestBodyComponents.queryItems = [URLQueryItem(name: "grant_type", value: "client_credentials")]
    request.httpBody = requestBodyComponents.query?.data(using: .utf8)
    
    let config = URLSessionConfiguration.default
    config.timeoutIntervalForRequest = TimeInterval(20)
    config.timeoutIntervalForResource = TimeInterval(20)
    let urlSession = URLSession(configuration: config)
    
    urlSession.dataTask(with:request, completionHandler: { (data, response, error) in
        completion(data, response, error)
    }).resume()

编码URL的扩展...

public extension String {

    func urlEncoded() -> String? {
        addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)?
            .replacingOccurrences(of: "&", with: "%26")
            .replacingOccurrences(of: "=", with: "%3D")
    }
}

有什么想法发生了什么?

非常感谢

I am trying to request an OAuth access token from HERE API. It is working however I am receiving intermittent errors. Around 50% of the time I am receiving this response:

{"errorId":"ERROR-8638f6e6-4fe9-420e-a31c-600f3062105b","httpStatus":401,"errorCode":401300,"message":"Signature mismatch. Authorization signature or client credential is wrong.","error":"invalid_client","error_description":"errorCode: '401300'. Signature mismatch. Authorization signature or client credential is wrong."}

Here is my code:

    let url = URL(string: "https://account.api.here.com/oauth2/token")!
    
    //Credentials
    let accessKeyId = "xxxxxxxxxxxxxxxx"
    let accessKeySecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    
    //Base String
    let timeStamp = String(Int(Date().timeIntervalSince1970))
    let nonce = String(Int(Date().timeIntervalSince1970 * 1000))
    
    let grant_type = "grant_type=client_credentials"
    let oauth_consumer_key = "&oauth_consumer_key=" + accessKeyId
    let oauth_nonce = "&oauth_nonce=" + nonce
    let oauth_signature_method = "&oauth_signature_method=HMAC-SHA256"
    let oauth_timestamp = "&oauth_timestamp=" + timeStamp
    let oauth_version = "&oauth_version=1.0"
    
    let paramsString = grant_type + oauth_consumer_key + oauth_nonce + oauth_signature_method + oauth_timestamp + oauth_version
    let baseString = "POST&" + url.absoluteString.urlEncoded()! + "&" + paramsString.urlEncoded()!
    
    //Key
    let secret = accessKeySecret + "&"
    let key = SymmetricKey(data: Data(secret.utf8))
    
    //Signature
    let signature = HMAC<SHA256>.authenticationCode(for: Data(baseString.utf8), using: key)
    let baseEncodedSignature = Data(signature).base64EncodedString().urlEncoded()!
    
    //Request
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    //Request Headers
    let authString = "OAuth oauth_consumer_key=\"\(accessKeyId)\",oauth_nonce=\"\(nonce)\",oauth_signature=\"\(baseEncodedSignature)\",oauth_signature_method=\"HMAC-SHA256\",oauth_timestamp=\"\(timeStamp)\",oauth_version=\"1.0\""
    request.setValue(authString, forHTTPHeaderField: "Authorization")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")
    
    //Request Body
    var requestBodyComponents = URLComponents()
    requestBodyComponents.queryItems = [URLQueryItem(name: "grant_type", value: "client_credentials")]
    request.httpBody = requestBodyComponents.query?.data(using: .utf8)
    
    let config = URLSessionConfiguration.default
    config.timeoutIntervalForRequest = TimeInterval(20)
    config.timeoutIntervalForResource = TimeInterval(20)
    let urlSession = URLSession(configuration: config)
    
    urlSession.dataTask(with:request, completionHandler: { (data, response, error) in
        completion(data, response, error)
    }).resume()

Extension for URL encoding...

public extension String {

    func urlEncoded() -> String? {
        addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)?
            .replacingOccurrences(of: "&", with: "%26")
            .replacingOccurrences(of: "=", with: "%3D")
    }
}

Any ideas what is happening?

Many thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

看轻我的陪伴 2025-02-06 03:42:36

嗨,您能在下面测试代码吗?

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

var semaphore = DispatchSemaphore (value: 0)

let parameters = "{\"grantType\":\"client_credentials\",\"expiresIn\":86400}"
let postData = parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "https://account.api.here.com/oauth2/token")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("OAuth oauth_consumer_key=\"*************\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1653538948\",oauth_nonce=\"fLlPzE4HBxJ\",oauth_version=\"1.0\",oauth_signature=\"vy9BT5dF3EBk0DR9JdxDu7StKeM%3D\"", forHTTPHeaderField: "Authorization")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
  guard let data = data else {
    print(String(describing: error))
    semaphore.signal()
    return
  }
  print(String(data: data, encoding: .utf8)!)
  semaphore.signal()
}

task.resume()
semaphore.wait()

Hi would you please test below code?

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

var semaphore = DispatchSemaphore (value: 0)

let parameters = "{\"grantType\":\"client_credentials\",\"expiresIn\":86400}"
let postData = parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "https://account.api.here.com/oauth2/token")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("OAuth oauth_consumer_key=\"*************\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1653538948\",oauth_nonce=\"fLlPzE4HBxJ\",oauth_version=\"1.0\",oauth_signature=\"vy9BT5dF3EBk0DR9JdxDu7StKeM%3D\"", forHTTPHeaderField: "Authorization")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
  guard let data = data else {
    print(String(describing: error))
    semaphore.signal()
    return
  }
  print(String(data: data, encoding: .utf8)!)
  semaphore.signal()
}

task.resume()
semaphore.wait()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文