iOS Missing grant_type - ios

I'm getting {"error_description":"Missing grant_type parameter value","error":"invalid_request"} when trying to request access token for the first time. My code is below:
let params : [String : String] =
["client_id" : clientID,
"client_secret" : secret,
"redirect_uri" : redirectURL,
"code" : code,
"grantType" : "authorization_code"
]
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("aapplication/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("\(request.HTTPBody!.length)", forHTTPHeaderField: "Content-Length")
What might be the problem? Thank you in advance.

Wow, I don't want to sound harsh, but there are multiple issues with this code.
You are not sending grant_type, but you do send grantType.
You are encoding the post body as application/json, but you are setting the Content-Type to be aapplication/x-www-form-urlencoded which seems to be a misspelling of application/x-www-form-urlencoded.
So two possible spelling issues and a content type mismatch.
Work out if you need to send application/x-www-form-urlencoded or application/json. Format the data and set the content type as needed.
Double check the spelling of everything.

Related

How to add username and password in WebService body and get token

I am working on swift and facing issue for fetching token from the server. I tried to solved it but in iOS it always fails. I put the api in hurl.it and Add header content type: Application/json, but I don't know how to add payload value : payload--{\"username\": \"username\",\"password\": \"userpassword\"} in Webservice request.
You can set your payload data in httpbody of Request Like Below Code.
var dicParameter : NSDictionary = ["username": "username","password":"password"]
var reqData : NSData = JSONSerialization.data(withJSONObject: dicParameter, options: JSONSerialization.WritingOptions.init(rawValue: 0))
var request : URLRequest = URLRequest.init(url: "url")
request.httpBody = reqData

"HTTP Status 400 - Bad Request - The request sent by the client was syntactically incorrect"?

I've done a http request with post parameters so many times, and I have now so many of them working just fine, I don't know why this one is not
this is the code
let url = NSURL(string: "bla bla lba")
let request = NSMutableURLRequest(URL: url)
let body = "id=\(requestClient!.id!)"
print("body = \(body)")
request.HTTPBody = body.dataUsingEncoding(NSASCIIStringEncoding)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
let session = NSURLSession.sharedSession()
let task1 = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
the server expects a form parameter named id and its value is long
when I print the id from swift (as you can see the code), I get this
id=1453045943881.0
and i get this error
HTTP Status 400 - Bad Request - The request sent by the client was syntactically incorrect.
sounds like the server said the request is not correct, but where is the wrong?
this is the server
#Path("/checkForResponses")
#POST
public Response checkForResponeses (#FormParam("id") long id) {

Differences between Using NSJSONSerialization.dataWithJSONObject and dataUsingEncoding to make up the HTTP body in Swift

I have seen two kinds of methods to make up the HTTP body.
First one is:
let url = NSURL(string: "http://example.com")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
let postString = "id=13&name=Jack"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
Second one is:
let url = NSURL(string: "http://example.com")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
let params = ["id":"13", "name":"Jack"] as Dictionary<String, String>
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
When I directly print out the request.HTTPBody the data is different. So I am wondering are there any differences between these two methods in terms of the implementation of the server side? Assuming I'am using PHP.
there're two format data.
in code using postString.dataUsingEncoding it will send data in urlencoded format. In client you must set request's Content-Type header to "application/x-www-form-urlencoded" or something like "application/x-www-form-urlencoded charset=utf-8"
in code using NSJSONSerialization.dataWithJSONObject it will send data in json format. In client you must set request's Content-Type header field to "application/json"
I'm iOS dev so I don't know about format's effect to server side PHP. to answer your question you must find difference between application/x-www-form-urlencoded and application/json format in server side

How to set HTTPBody?

In Swift I'm trying to make a post request (using the NSURLSession) to sign in a user to a WebAPI web services.
The Url is www.myurltest.com/Token and I must pass the following string as POST body:
grant_type=password&username=MyUsername&password=MyPassword.
So in Swift I've make:
let session = NSURLSession.sharedSession();
let url = NSURL(string:"www.myurltest.com/Token");
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
Now I want to set the POST body (that is a string) but I don't know how:
request.HTTPBody = ?????
Thanks.
You're almost there, you just need to turn the string into an NSData object. If your string is in a variable named body, your code will look like request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)

what's the equivalent of this curl request in swift

I've tried lots of different things to recreate this curl request, and I'm going insane. If someone could help, I'd be very much appreciative.
curl -H "Content-Type: application/json" -X POST --data '[{"a": 4, "b": 5, "c": 6}]' \ -u username:password \ https://www.mywebsite.com
My latest attempt is:
let loginString = NSString(format: "%#:%#", username!, password!)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions(nil)
var url: NSURL = NSURL(string: "www.mywebsite.com")!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
request.addValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let bodyData = JSON(data!).rawString(encoding: NSUTF8StringEncoding, options: NSJSONWritingOptions.allZeros)
request.HTTPBody = bodyData?.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
if let tabBarVC : TabBarController = self.tabBarController as? TabBarController {
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
}
In this example, data is a dictionary ([String:String]) and JSON is form SwiftyJSON.
The above sends NSData to the server, which is encoded and the server doesn't like. The request is getting through, but the server can't read the data right. What do I need to do to exactly replicate the curl request above? I'm stuck!
Updated to reflect good responses below.
I did attempt to use application/json for content-type, but this returns the message:
{"status": "Internal error JSON uploads must be formatted as an array of objects", "code": 400, "version": "v1"}
It seems like progress if I use text/plain (as above) I get:
{"status": "Column a is missing", "code": 400, "version": "v1"}
Which I can't seem to figure out.
A couple of thoughts:
If nothing else, the line that says:
request.addValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
Should be:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
Your curl clearly states that the content type header was supposed to be JSON, so I'd set that accordingly.
Also, the line that says:
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Accept-encoding")
That's clearly not correct, either. I think you meant Accept not Accept-encoding, plus the server is undoubtedly not responding with a x-www-form-urlencoded response, anyway.
I would simply remove that line.
Your URL is missing the scheme (the http://), but I assume that was removed when editing your question, because I don't think it would work without that, but you assured us that the server did receive the request.
I'd suggest you consider a tool like Charles. Watch the request from curl and then again from your code. Compare and contrast and identify how they differ. Using this, you should be able to diagnose precisely what's going on and where the discrepancy rests.
You say:
The request is getting through, but the server can't read the data right.
If the problem persists, you should share with us how you know the request is getting through and what you mean by "can't read the data right."

Resources