I was hoping for someone to review my current project, which was created in Swift and uses a PHP web service. I'm not worried about UI elements, as this is just a 'test' project, but I'm concerned about two things: using the best practices and security. I'm concerned that the SQL query is not safe, among other things.
user.swift
import Foundation
class User: NSObject {
var firstName: String?
var lastName: String?
var username: String
var password: String
var email: String?
var recievedJSON: NSMutableData = NSMutableData()
var userData: [[String: String]]!
var verified: Bool = false
required init(username: String, password: String) {
self.username = username
self.password = password
}
init(firstName: String, lastName: String, username: String, password: String, email: String) {
self.firstName = firstName
self.lastName = lastName
self.username = username
self.password = password
self.email = email
}
func attemptRegister() {
var variables: [String] = ["firstname=" + self.firstName! + "&"]
variables.append("lastname=" + self.lastName! + "&")
variables.append("username=" + self.username + "&")
variables.append("password=" + self.password + "&")
variables.append("email=" + self.email!)
request("https://codekaufman.com/register.php", variables: variables)
}
func attemptSignIn() {
var variables: [String] = ["username=" + self.username + "&"]
variables.append("password=" + self.password)
request("https://codekaufman.com/login.php", variables: variables)
println("Attempting sign-in...")
}
private func request(urlPath: String, variables: [String]?) {
var url: NSURL = NSURL(string: urlPath)!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
if(variables != nil) {
request.HTTPMethod = "POST"
var bodyData: NSString = ""
for item in variables! {
bodyData = bodyData + NSString(string: item)
}
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
}
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
connection.start()
println("Connection started.")
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.recievedJSON.appendData(data)
println("Data recieved.")
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
userData = parseJSON(recievedJSON)
if(userData != nil) {
println("Data recieved:")
println(userData[0])
} else {
println("No data recieved.")
}
}
func parseJSON(inputData: NSData) -> [[String: String]]? {
var error: NSError?
var userData: [[String: String]]!
userData = NSJSONSerialization.JSONObjectWithData(inputData, options: NSJSONReadingOptions.MutableContainers, error: &error) as? [[String: String]]
if (userData != nil) {
println("NSData had data, printing and returning.")
println(userData)
return userData
} else {
println("NSData empty, returning nil.")
return nil
}
}
}
register.php
<?php
error_reporting(E_ALL);
ini_set('display errors', 1);
// Don't worry about this, I'm aware of the security issue. :)
$username = '';
$password = '';
try {
$dbh = new PDO('mysql:host=localhost; dbname=codeggdj_users', $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$recievedUsername = $_POST['username'];
$recievedPassword = password_hash($_POST['password'], PASSWORD_BCRYPT);
$recievedFirstName = $_POST['firstname'];
$recievedLastName = $_POST['lastname'];
$sth = $dbh->prepare("INSERT INTO users (username, password, first_name, last_name) VALUES (?, ?, ?, ?)");
$sth->execute([$recievedUsername, $recievedPassword, $recievedFirstName, $recievedLastName]);
} catch(PDOException $e) {
echo $e->getMessage();
}
?>
login.php
<?php
error_reporting(E_ALL);
ini_set('display errors', 1);
// Don't worry about this, I'm aware of the security issue. :)
$username = '';
$password = '';
try {
$dbh = new PDO('mysql:host=localhost; dbname=codeggdj_users', $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$recievedUsername = $_POST['username'];
$recievedPassword = $_POST['password'];
$sth = $dbh->prepare('SELECT password FROM users WHERE username = ?');
$sth->execute([$recievedUsername]);
if($sth->rowCount()) {
$row = $sth->fetch(PDO::FETCH_OBJ);
if(password_verify($recievedPassword, $row->password)) {
$sth = $dbh->prepare('SELECT id, username, first_name, last_name FROM users WHERE username = ?');
$sth->execute([$recievedUsername]);
echo json_encode($row = $sth->fetchAll(PDO::FETCH_ASSOC));
} else {
echo 'Incorrect Password';
}
} else {
echo 'Incorrect Username';
}
} catch(PDOException $e) {
echo $e->getMessage();
}
?>