从Swift发送HTTP post请求到数据库mysql

问题描述:

I am making a signup system( getting users information such as name, email) using Swift as a front end, php as a backend, and mysql as a database. ( using my own server, not localhost) and trying to send HTTP post request from Swift to insert data to user tables.(mySQL). I'm using a secure https url.

The problem is that when I try to pass data (firstname, last name, email, password), I always get a bad request (400) “Missing required information” like the screenshot and can’t let users to sign up… enter image description here

If i could pass the data, I should get the success response (200) “Registration successful”. The function inside the php is called so I assume there’s nothing wrong with my php code but the Swift code.

I want to know the reason why I cannot pass the data to my server(maybe from MySQL setting?). Thanks in advance and happy coding!

My php file(file name: registerUser.php):

<?php

  require("Conn.php");
  require("MySQLDAO.php");

  $returnValue = array();

  if(empty($_REQUEST["userEmail"]) || empty($_REQUEST["userPassword"]) || empty($_REQUEST["userFirstName"]) || empty($_REQUEST["userLastName"]))

  {

    $returnValue["status"]="400";
    $returnValue["message"]="Missing required information";
    echo json_encode($returnValue);
    return;
  }

  $userEmail = htmlentities($_REQUEST["userEmail"]);
  $userPassword = htmlentities($_REQUEST["userPassword"]);
  $userFirstName = htmlentities($_REQUEST["userFirstName"]);
  $userLastName = htmlentities($_REQUEST["userLastName"]);

  //generate secured passowrd 
  $salt = openssl_random_pseudo/bytes(16);
  $secured_password = sha1($userPassword . $salt);

  $dao = new MySQLDAO(Conn::$dbhost, Conn::$dbuser, Conn::$dbpassword, Conn::$dbname);
  $dao->openConnection();

  //check if user with provided username is available 
  $userDetails = $dao->getUserDetails($userEmail);
  if (!empty($userDetails))
  {
    $returnValue["status"]="400";
    $returnValue["message"]="Please choose a different email address";
    echo json_encode($returnValue);
    return; 

  }

  //Register new User 
  $result = $dao->registerUser($userEmail, $userFirstName, $userLastName, $secured_password, $salt);

  if($result){

    $userDetails = $dao->getUserDetails($userEmail);
    $returnValue["status"] = "200";
    $returnValue["message"] = "Registration successful";
    $returnValue["userId"] = $userDetails["user_id"];
    $returnValue["userFirstName"] = $userDetails["first_name"];
    $returnValue["userLastName"] = $userDetails["last_name"];
    $returnValue["userEmail"] = $userDetails["email"];

  } else {
      $returnValue["status"]="400";
      $returnValue["message"]="Couldn't register";

  }

$dao->closeConnection();

echo json_encode($returnValue);

?>

My Swift code:

 lazy var submitButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor(red:0.09, green:0.51, blue:0.92, alpha:1.0)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle("Signup", for: .normal)
    button.setTitleColor(.white, for: .normal)
    button.addTarget(self, action: #selector(handleSubmit), for: .touchUpInside)
    return button

}()

func handleSubmit() {
    guard let userFirstName = userFirstNameTextField.text, let userLastName = userLastNameTextField.text, let userEmail = emailTextField.text, let userPassword = passwordTextField.text, let repeatPassword = repeatPasswordTextField.text

        else {
            print("Form is not valid")
            return
    }

    if (userPassword != repeatPassword) {
        self.displayAlertMessage(userMessage: "Passwords do not match")
        return
    }

    if (userFirstName.isEmpty || userLastName.isEmpty || userEmail.isEmpty || userPassword.isEmpty) {

        self.displayAlertMessage(userMessage: "All fields are required")
        return
    }

let myUrl = NSURL(string: "https://my URL name/registerUser.php")
let request = NSMutableURLRequest(url: myUrl! as URL)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

let postString = "userEmail=\(userEmail)&userFirstName=\(userFirstName)&userLastName=\(userLastName)&userPassword=\(userPassword)"

request.httpBody = postString.data(using: String.Encoding.utf8)

let task = URLSession.shared.dataTask(with: request as URLRequest) {(data:Data?, response:URLResponse?, error: Error?) -> Void in

    DispatchQueue.main.async {

        if error != nil {
            self.displayAlertMessage(userMessage: "Error")
            return
        }

        do {

        let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

        if let parseJSON = json {
            let userId = parseJSON["userId"] as? String

            if (userId != nil) {

            let myAlert = UIAlertController(title: "Success", message: "Registration Successful", preferredStyle: UIAlertControllerStyle.alert)
            let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)
            myAlert.addAction(okAction)
                self.present(myAlert, animated: true, completion: nil)

        } else {

                print(123)
            let errorMessage = parseJSON["message"] as? String
                if (errorMessage  != nil) {

                self.displayAlertMessage(userMessage: errorMessage!)
                }
            }
        }

    } catch {
        print(error)

    }

    }

    }

    task.resume()
}

Since you are getting the 400 error "missing required information" it's not a problem of being able to store the information in a database but rather getting the values from the POST request (triggered by this line):

if(empty($_REQUEST["userEmail"]) || empty($_REQUEST["userPassword"]) || empty($_REQUEST["userFirstName"]) || empty($_REQUEST["userLastName"])))

I would start by printing out those values. Are any of them showing up? is only one empty? If they are all empty the problem is how you sent the params from the front end.