Swift - POST request recognises as GET on server - php

Making a simple POST req from Swift to Apache/PHP.
Swift code:
let request = NSMutableURLRequest(URL: NSURL(string: "http://dzr.lenyapugachev.ru/createMember")!)
request.HTTPMethod = "POST"
let postString = "id=13&name=Jack"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
println("response = \(response)")
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("responseString = \(responseString)")
}
task.resume()
PHP:
<?php
echo $_SERVER['REQUEST_METHOD']."\n";
var_dump($_POST);
?>
Output:
GET
array(0) {}
So, it doesn't act as POST for server. I've also tried Alamofire and SwiftHTTP, same effect.
Please, good people, help.

It is indeed a HTTP POST request. Nothing wrong with your code. Using Charles (a HTPP debug proxy) I see that your request get redirected (301 HTTP)
You need to fix your server's code / .httpaccess configuration
Request:
POST /createMember HTTP/1.1
Host dzr.lenyapugachev.ru
Accept-Encoding gzip, deflate
Content-Type application/x-www-form-urlencoded
Content-Length 15
Accept-Language en-us
Accept */*
Connection keep-alive
User-Agent 29530174/1 CFNetwork/711.2.23 Darwin/13.4.0
Response:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved here.</p>
</body></html>

check your url
for PHP server it should be .Php file
used as
let request = NSMutableURLRequest(URL: NSURL(string: "http://dzr.lenyapugachev.ru/createMember.php")!)
also if u send parameter your php server request like
let request = NSMutableURLRequest(URL: NSURL(string: "http://dzr.lenyapugachev.ru/createMember.php?id=13&name=Jack")!)
refer this tutorial it include both php anD swift code to send post request TUTORIAL: POST TO WEB SERVER API IN SWIFT USING NSURLCONNECTION

Related

woocommerce api 401 error on Xcode8 Request

While trying to link the woo-commerce api's generated on xcode8 I am getting error 401 (on googleing a bit found its authentication error) however the same api link and the keys seem to work fine on browser.
Adding the code snip of xcode for reference.
let urlString = "https://serverUrl.com"
func downloadJsonWithURl(){
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url as! URL)
//keys for authentication
request.addValue("A KEY", forHTTPHeaderField: "Consumer-key")
request.addValue("A SECRET", forHTTPHeaderField: "Secret-key")
URLSession.shared.dataTask(with: (url as? URL)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
print (jsonObj as Any)
}
}) .resume()
}
after a bit poking . i got fix this.
just modify the .plist file
add App Transport Security Settings and within that Allow Arbitrary Loads in Web Content and Allow Arbitrary Loads to YES.
info.plist

Lamp web server (trusting ssl certificates)

So this may be a little broad, but I will be as specific as possible with what I am working on.
Currently I am developing an iPhone app using swift 3. This app performs a post request to a php file located on a lamp server that is on a different network. The server is primarily being used to simply take the data sent from the app and store it into some mysql tables.
Currently, I am doing this.
func sendToServer(firstEntry: String, secondEntry: String, serverAddr: String){
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
let uid = firstEntry
let gender = secondEntry
let request = NSMutableURLRequest(url: NSURL(string: serverAddr)! as URL)
request.httpMethod = "POST"
let postString = "UID=\(uid)&Gender=\(gender)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: #escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}
This sends the data over like it should. But I would like to see if anyone can answer these couple questions.
Is there a way to get a trusted certificate without having a domain name?
If I do it this way will there be issues with the app getting rejected for this?
Thanks

Swift3: HTTP POST request with parameters divided by "/"

This is the acceptable POST request that server(using codeigniter) accepts.
As it is shown, it doesn't take keys, but only values.
The first value starts with "/", and "/" is used between values.
http://example.com/index.php/api/signup/value01/value02/value03
I have this code, written in Swift3.
let serverUrl = "http://example.com/index.php/api/signup"
let parameterString = "/value01/value02/value03"
let url: URL = URL(string: serverUrl)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
request.httpBody = parameterString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
}) task.resume()
It gets an error, and the server responds that it didn't receive any parameter.
But, if I copy paste the below code to Browser, it works perfect.
http://example.com/index.php/api/signup/value01/value02/value03
The swift3 code worked for another server, which accepted POST requests written this way.
http://example.com/api?key=value&key=value
Thank you #Tj3n #Leo Dabus #GoodSp33d !
I was able to solve the problem, using your suggestions.
The server php also used "URL-encode RFC 1738 (e.g. "%E6%84%9B" for "愛")" for certain string values.
So, I added
let newString = oldString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)!
to encode some string values and the problem solved.
So, this is the solution in a simplified version.
let serverUrl = "http://example.com/index.php/api/signup/value01/value02/value03"
let url: URL = URL(string: serverUrl)!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
}) task.resume()
This is the real POST request url that my code sent.
http://example.com/index.php/api/signup/1282283772/none/0204291/%E6%84%9B/0/70/null

Make contact form for iOS app with Swift and PHP

I want to create a contact form where the user can leave me a message (and name and phone number…) and send it to me.
But I don't know how to do this because I never dealt with thinks like this before.
My own suggestion is to $_POST the content from TextField and TextView to a PHP script on my server. This will handle the content. (Either send an email to me with mail() or store it in a file on the server. The PHP script is no problem for me.)
Is that way reasonable? What is the common way to do that, to leave a feedback or something like this to the developer?
P.S. I know there's a way that the user sends me an email from inside the app. But I don't like this way.
That seems reasonable to me. You could just write a function in swift to send to send get or post parameters like so:
func postParamRequest(resourceURL: String, postData: String, completionHandler: ((NSURLResponse?, NSData?, NSError?) -> Void)) {
let request : NSMutableURLRequest = NSMutableURLRequest()
request.URL = NSURL(string: resourceURL)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse?, data: NSData?, error: NSError?) in
completionHandler(response, data, error)
})
}
You can then just call that function and get the callback of the response, data, and any errors too (the postData should be [key: value]) for the POST parameters. Like so:
postParamRequest("theUrlToYourScript", postData: "key1=value&key2=value&key3=value") { (response, data, error) in
print(data)
}
In your PHP script you could then retrieve the data with something like this: $_POST["paramName"].

How to establish a connection to a web server with NSURL in which variables can be passed securely via URL to PHP script

I am using Swift's NSURL function to connect to a PHP script that I can use to interact with a MySQL database. Everything is running smoothly except for the insecurity of the variables passed in the URL via POST. If someone were to intercept these variables it would pose an enormous security risk to my application. I have researched the subject extensively however I have hit a wall. Is an SSL certificate enough to secure the URL? I am not passing the variables through the literal URL but a POST method. As far as I know, the SSL certificate provides security for the data passed AFTER the initial connection (meaning that the data originally passed via POST and the URL are not secure). So essentially, how do I go about passing variables to a web server securely?Here is the code I am using to establish the connection:
let myUrl = NSURL(string: "http://testsite.com/login.php”)
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = “username=bob&password=123"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
if let responseData = data {
let responseString = NSString(data: responseData, encoding: NSUTF8StringEncoding)
if error != nil {
print("Error: \(error)")
}
dispatch_async(dispatch_get_main_queue()) {
}
}
} else {
self.sendAlert("Error", message: "Unable to establish connection")
}
}
You can refer to raywenderlich tutorials for setting up the iOS part of it. This tutorial is for connection between ruby rails and swift. It has sign in, sign up and token system, it also includes encryption.
The tutorial uses httpBody to pass the information, you can stick with that or modify to header instead to personalise your codes as required.
request.addValue("bob", forHTTPHeaderField: "username")
request.addValue("123", forHTTPHeaderField: "password") // add AES Encryption.
Also, you can implement a token system instead of passing your username and password. You would however have to pass it initially to get the token.

Categories