[GH-ISSUE #80] POST request Authentication Failed #51

Closed
opened 2026-03-03 16:45:12 +03:00 by kerem · 12 comments
Owner

Originally created by @gabriel-jones on GitHub (Jul 6, 2015).
Original GitHub issue: https://github.com/OAuthSwift/OAuthSwift/issues/80

I am trying to upload a piece of data to Intuit's Quickbooks API, by doing something like this:

//Set parameters for request
        let parameters: [String: AnyObject] = [
            "NameOf":"Employee",
            "EmployeeRef":[
                "value":"64"
            ],
            "CustomerRef":[
                "value":"21"
            ],
            "ItemRef":[
                "value":"1"
            ],
            "BreakHours": 1,
            "BreakMinutes":0,
            "StartTime": "example start time",
            "EndTime": "example end time",
            "Description": "example description",
            "domain": "QBO",
            "sparse": false
        ]
        //Send a POST request to the Quickbooks API endpoint
        oauthswift.client.post("https://sandbox-quickbooks.api.intuit.com/v3/company/<companyID>/timeactivity", parameters:  parameters, success: {
            data, response in
            println("success")
            }, failure: {
            error in
            println(error.localizedDescription)
        })

But I get back an error from the server saying the content type is not valid. So I tried changing (in the OAuthSwiftClient) where it says request.encodeParameters = true to request.encodeParameters = false, and this gives me the error from the server saying the application's authentication failed, and the OAuth signature is not included in the response string.

I should probably add that doing a GET request works fine.

Has anybody else had these problems?

Originally created by @gabriel-jones on GitHub (Jul 6, 2015). Original GitHub issue: https://github.com/OAuthSwift/OAuthSwift/issues/80 I am trying to upload a piece of data to Intuit's Quickbooks API, by doing something like this: ``` //Set parameters for request let parameters: [String: AnyObject] = [ "NameOf":"Employee", "EmployeeRef":[ "value":"64" ], "CustomerRef":[ "value":"21" ], "ItemRef":[ "value":"1" ], "BreakHours": 1, "BreakMinutes":0, "StartTime": "example start time", "EndTime": "example end time", "Description": "example description", "domain": "QBO", "sparse": false ] //Send a POST request to the Quickbooks API endpoint oauthswift.client.post("https://sandbox-quickbooks.api.intuit.com/v3/company/<companyID>/timeactivity", parameters: parameters, success: { data, response in println("success") }, failure: { error in println(error.localizedDescription) }) ``` But I get back an error from the server saying the content type is not valid. So I tried changing (in the OAuthSwiftClient) where it says `request.encodeParameters = true` to `request.encodeParameters = false`, and this gives me the error from the server saying the application's authentication failed, and the OAuth signature is not included in the response string. I should probably add that doing a GET request works fine. Has anybody else had these problems?
kerem 2026-03-03 16:45:12 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@phimage commented on GitHub (Aug 7, 2015):

You set request.encodeParameters = false in framework code to force encode json (and add json header), code maybe not reachable without hacking the framework...

For OAuth v1 there is a method OAuthSwiftClient.authorizationHeaderForMethod
I think your json is merged into the Authorization header, so the website does'nt understand anything

You can test by modifying other code into OAuthSwiftClient

 func request(url: String, method: String, parameters: Dictionary<String, AnyObject>, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) {

replace parameters here with empty dictionnary

request.headers = ["Authorization": OAuthSwiftClient.authorizationHeaderForMethod(method, url: url, parameters: parameters, credential: self.credential)]
<!-- gh-comment-id:128841305 --> @phimage commented on GitHub (Aug 7, 2015): You set `request.encodeParameters = false` in framework code to force encode json (and add json header), code maybe not reachable without hacking the framework... For OAuth v1 there is a method `OAuthSwiftClient.authorizationHeaderForMethod` I think your json is merged into the Authorization header, so the website does'nt understand anything You can test by modifying other code into `OAuthSwiftClient` ``` swift func request(url: String, method: String, parameters: Dictionary<String, AnyObject>, success: OAuthSwiftHTTPRequest.SuccessHandler?, failure: OAuthSwiftHTTPRequest.FailureHandler?) { ``` replace `parameters` here with empty dictionnary ``` swift request.headers = ["Authorization": OAuthSwiftClient.authorizationHeaderForMethod(method, url: url, parameters: parameters, credential: self.credential)] ```
Author
Owner

@gabriel-jones commented on GitHub (Sep 2, 2015):

@phimage Could you give an example of all changes to the request function in OAuthSwiftClient?

<!-- gh-comment-id:137188767 --> @gabriel-jones commented on GitHub (Sep 2, 2015): @phimage Could you give an example of all changes to the request function in OAuthSwiftClient?
Author
Owner

@phimage commented on GitHub (Sep 2, 2015):

I am just taking about one little change already described upper with function name and line of code
empty dico : Dictionary<String, AnyObject>()
instead of parameters

<!-- gh-comment-id:137206296 --> @phimage commented on GitHub (Sep 2, 2015): I am just taking about one little change already described upper with function name and line of code empty dico : Dictionary<String, AnyObject>() instead of parameters
Author
Owner

@gabriel-jones commented on GitHub (Sep 3, 2015):

@phimage This throws the error 400: Bad Request: oauth_problem=parameter_absent&oauth_parameters_absent=oauth_callback
For when it tries to redirect to login page, not even to post request yet.

<!-- gh-comment-id:137417554 --> @gabriel-jones commented on GitHub (Sep 3, 2015): @phimage This throws the error 400: Bad Request: `oauth_problem=parameter_absent&oauth_parameters_absent=oauth_callback` For when it tries to redirect to login page, not even to post request yet.
Author
Owner

@gabriel-jones commented on GitHub (Sep 3, 2015):

@phimage So I reviewed it with Intuit support and everything seems fine. They suspect the problem is with the HTTP body not being encoded before the signature is generated. Is this a problem with the framework, and has anybody had difficulty with POST requests before?

<!-- gh-comment-id:137560709 --> @gabriel-jones commented on GitHub (Sep 3, 2015): @phimage So I reviewed it with Intuit support and everything seems fine. They suspect the problem is with the HTTP body not being encoded before the signature is generated. Is this a problem with the framework, and has anybody had difficulty with POST requests before?
Author
Owner

@olivier38070 commented on GitHub (Sep 28, 2015):

Hi,

on my side, with smugmug (I don't have account elsewhere to test), POST and PUT are not working.
I obtain always invalid signature feedback.
I tried to change the url, the parameter, and did a lot of test, without any success.

<!-- gh-comment-id:143689052 --> @olivier38070 commented on GitHub (Sep 28, 2015): Hi, on my side, with smugmug (I don't have account elsewhere to test), POST and PUT are not working. I obtain always invalid signature feedback. I tried to change the url, the parameter, and did a lot of test, without any success.
Author
Owner

@janakmshah commented on GitHub (Nov 9, 2015):

Did anyone find a fix for this?

<!-- gh-comment-id:154901691 --> @janakmshah commented on GitHub (Nov 9, 2015): Did anyone find a fix for this?
Author
Owner

@phimage commented on GitHub (Nov 19, 2015):

No fix currently

There is some confusion between query URL parameters and HTTP Body
If POST, parameters become "body" but also used in authentification signature, like parameters was in query (so we have a wrong signature)
Then encodeParameters is always true so there is never json content type (maybe I will remove that and check if content type added)

I can provide some network code not tested yet (you could use also other remote framework like alamofire)

var url = NSURL(string: "apiurlstring")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
var headers = oauthswift.client.credential.makeHeaders(url, method: "POST", parameters: [:])  // here with create the authentification headers
// here add additional headers "Content-type", etc..
request.headers = headers

request.HTTPBody = NSData from your json

let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(req) { data, response, error in
    if nil != error {
        // something went wrong
    }
    else {

    }
}
task.resume()
<!-- gh-comment-id:158084093 --> @phimage commented on GitHub (Nov 19, 2015): No fix currently There is some confusion between query URL parameters and HTTP Body If POST, parameters become "body" but also used in authentification signature, like parameters was in query (so we have a wrong signature) Then encodeParameters is always true so there is never json content type (maybe I will remove that and check if content type added) I can provide some network code not tested yet (you could use also other remote framework like alamofire) ``` swift var url = NSURL(string: "apiurlstring")! let request = NSMutableURLRequest(URL: url) request.HTTPMethod = "POST" var headers = oauthswift.client.credential.makeHeaders(url, method: "POST", parameters: [:]) // here with create the authentification headers // here add additional headers "Content-type", etc.. request.headers = headers request.HTTPBody = NSData from your json let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(req) { data, response, error in if nil != error { // something went wrong } else { } } task.resume() ```
Author
Owner

@phimage commented on GitHub (Nov 22, 2015):

For inuit oauth_body_hash is maybe necessasy to sign JSON or XML posted body http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html

<!-- gh-comment-id:158807669 --> @phimage commented on GitHub (Nov 22, 2015): For inuit oauth_body_hash is maybe necessasy to sign JSON or XML posted body http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html
Author
Owner

@gabriel-jones commented on GitHub (Nov 22, 2015):

Is this something you could add to the library? If so that would be great

<!-- gh-comment-id:158815032 --> @gabriel-jones commented on GitHub (Nov 22, 2015): Is this something you could add to the library? If so that would be great
Author
Owner

@phimage commented on GitHub (Nov 23, 2015):

Yes but I have no time this week and maybe not the next one.

This is not easy because OAuthSwift create the header before filling the body, there is some change to do (maybe fill body before, or extract a body creation only function)

<!-- gh-comment-id:158929016 --> @phimage commented on GitHub (Nov 23, 2015): Yes but I have no time this week and maybe not the next one. This is not easy because OAuthSwift create the header before filling the body, there is some change to do (maybe fill body before, or extract a body creation only function)
Author
Owner

@phimage commented on GitHub (Nov 25, 2015):

No need for body hashing, I have done a POST request with success on Inuit sandbox

For that, add headers to encode in JSON body and remove parameters from signature

I add an example in demo app for inuit

var jsonUpdate = .... 
oauthswift.client.post("https://sandbox-quickbooks.api.intuit.com/v3/company/\(companyId)/account?operation=update", parameters: jsonUpdate,
    headers: ["Accept": "application/json", "Content-Type":"application/json"],
       success: {
           data, response in
          print(data)
      }, failure: { error in
          print(error)
})

XML is not supported yet, new issue(feature, enhancement) for it if necessary
two solution:

  • allow user to give an encoded body, and not use parameters
  • allow to convert parameters to XML (not available in Foundation I think, so user must configure an handler to encode according to encode type)
<!-- gh-comment-id:159693378 --> @phimage commented on GitHub (Nov 25, 2015): No need for body hashing, I have done a POST request with success on Inuit sandbox For that, add headers to encode in JSON body and remove `parameters` from signature I add an example in demo app for inuit ``` swift var jsonUpdate = .... oauthswift.client.post("https://sandbox-quickbooks.api.intuit.com/v3/company/\(companyId)/account?operation=update", parameters: jsonUpdate, headers: ["Accept": "application/json", "Content-Type":"application/json"], success: { data, response in print(data) }, failure: { error in print(error) }) ``` XML is not supported yet, new issue(feature, enhancement) for it if necessary two solution: - allow user to give an encoded body, and not use `parameters` - allow to convert `parameters` to XML (not available in Foundation I think, so user must configure an handler to encode according to encode type)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/OAuthSwift#51
No description provided.