POST not working SWIFT PHP [closed] - php

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I have a problem on Xcode using Swift 3.0, i want to store information in a mysql database with php. The php code is reached but always return failure on the insert request. I don't know, it works fine with android. Here's my code :
Swift :
#IBAction func SignUp(_ sender: UIButton) {
var Name1: String = Name.text!
var Prenom: String = PRENAME.text!
var add: String = Addr.text!
var code:String = CP.text!
var mail:String = Email.text!
var pass:String = password.text!
var request = URLRequest(url: URL(string: "http://www.example.com/myscript.php")!)
request.httpMethod = "POST"
let postString = "name=\(Name1)&pname=\(Prenom)&add=\(add)&pc=\(code)&mail=\(mail)&pass=\(pass)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
}
And my PHP code :
<?php
$reponse = array();
$pseudo = $_POST['name'];
$score = $_POST['pname'];
$add = $_POST['add'];
$pc = $_POST['pc'];
$mail = $_POST['mail'];
$password = $_POST['pass'];
$mysqli = new MySQLi("host","root","pass","user");
$result = $mysqli->query("INSERT INTO compte (Name,Name2,Ad,code,maiil,pass) VALUES('$pseudo','$score','$add','$pc','$mail','$password')");
if ($mysqli->connect_error){
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
if($result){
$response["success"] = 1;
$response["message"] = "SUCCESS!";
echo json_encode($response);
}
else{
$response["success"] = 0;
$response["message"] = "FAILURE!";
echo json_encode($response);
}

A couple of thoughts:
On failure, you should set message to $mysqli->error instead of just "FAILURE!", so you can see why it failed.
I'd suggest moving the "did connection fail" logic before you attempt the query. I'd also suggest you change this to output JSON that says that the connection failed and exit, rather than just performing die. Later, as you improve the Swift code to parse errors, it will be useful to keep all server messages as JSON.
You should change the PHP to escape the parameters using real_escape_string. In the absence of that, if any of your values included a ' character, your SQL will fail. (You're also susceptible to SQL injection attacks.)
You should change the Swift to percent escape the values included in the httpBody of the request. See https://stackoverflow.com/a/28027627/1271826 for examples. Or use something like Alamofire that takes care of this for you. But as it stands:
If any of these values included a + character, it would likely be replaced with a space.
If any of these values included a & character, it would end up truncating that field.
If any of these values included any other reserved character, the whole query could fail.
While not essential, I'd suggest :
In the Swift code, set the Content-Type header of the request to application/x-www-form-urlencoded and the Accept header of the request to application/json.
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
In the PHP code, set the Content-Type header to application/json before you echo the JSON:
header("Content-Type: application/json");
While this is optional, if you later adopt a library, like Alamofire, which performs validation for these standard headers, it will make your life easier.

don't forget to add this to info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
so you can fire http or https requests
-- make sure any of you parameters don't contain & so value can be sent successfully or replace it with %26

Sorry, my bad everything is OK, by doing the sqli->error, i have found the error, i have forgotten that i don't let duplicate the mail in my database. So thank you very much everyone. And have a good week end !

Related

Cannot POST base64 image content over http to PHP server

I have read all the other threads but my problem is a mix of those. So I am trying to send some content over to a php server through HTTP in swift. Everything works fine until I append an image base64 content to the body of the http tag. I checked the php backend max post size, wasnt it. I copy pasted the image content that was generated in swift and pasted it in chrome and image was there, so image is not faulty.
This is the sample code of what I have
let url = NSURL(string: "https:example.com/endpoint")
// let session = NSURLSession.sharedSession();
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
var body = "csrf_token=" + (token.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())! as String)
body += "&email=" + (email?.text)!
body += "&first_name=" + (firstName?.text)!
body += "&last_name=" + (lastName?.text)!
body += "&password=" + password!.text!
//body += "&image_content=" + imageContent
body += "&confirm_password=" + confirmPassword!.text!
body += "&provider=" + provider
body += "&pictureURL=" + pictureURL
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)
request.addValue("https:example.com/", forHTTPHeaderField: "origin")
request.addValue("https:example.com/endpoint", forHTTPHeaderField: "referrer")
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
print(data)
print(response)
return;
}
let dataString = NSString(data :data!, encoding: NSUTF8StringEncoding);
print(dataString)
if ((response as! NSHTTPURLResponse).statusCode == 200) {
dispatch_async(dispatch_get_main_queue(), {
self.performSegueWithIdentifier("loginAfterSignup", sender: nil)
})
}
else {
dispatch_async(dispatch_get_main_queue(), {
print((response as! NSHTTPURLResponse).statusCode)
print("error code, could not sign up and login")
})
}
}
task.resume()
So when I uncomment the line with the base64 string content, I go to the throwback call and it prints the "error".
I have no clue why its not sent through http. Is there a rule I have to obey? Do I have to set a certain http header once I append a large string? Am I missing something here?
Thanks
Yep, it was a stupid Apache settings error. I have previously modified max_post_size and got nothing. However this time I modified the max request body parameter and I could finally send data to the server.

Incomplete Base64 when sending to server

I am trying to send an image to server, but the image should be in Base64 format. I am using this function to send it:
func upload_signature_staff(ticket: NSString){
let defaults = NSUserDefaults.standardUserDefaults()
let stringOne = defaults.stringForKey(defaultsKeys.staff_id)
let stringtwo = defaults.stringForKey(defaultsKeys.mst_customer)
let sig = defaults.stringForKey("staff_signature")
let request = NSMutableURLRequest(URL: NSURL(string: "http://xxxxxxxxxxxxx/upload.php")!)
request.HTTPMethod = "POST"
let postString = "action=add_signature&mst_customer=\((stringtwo!))&ticket=\((ticket))&signature=\((sig!))&current_user=\((stringOne!))&item_type=10"
print(postString)
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
//self.performSegueWithIdentifier("goto_main2", sender: self)
}
The sig variable holds the Base64 string, it is being printed in my console so I can verify that the string is correct. I am also printing the postString and upon inspection it is also correct that the signature is matching the Base64 String. But when I open phpmyadmin, I see the field of my image with incomplete Base64 string, maybe 1/4 is just there.
Here's my php code, in case you want to see it:
<?php
require_once("../c.php");
$action = trim($_POST['action']);
if($action == "add_signature"){
$mst_customer = trim($_POST['mst_customer']);
$ticket = trim($_POST['ticket']);
$signature = trim($_POST['signature']);
$current_user = trim($_POST['current_user']);
$item_type = trim($_POST['item_type']);
$inputtime = time();
$sql = "INSERT INTO ticket_items SET mst_customer = '$mst_customer', ticket = '$ticket', ticket_item_type = '$item_type', details = '$signature', addedby = '$current_user', lastupdate = '$inputtime' ";
mysql_query($sql) or die(mysql_error());
}
?>
I think this was solved in the comments but here's a recap:
Inserting base64 strings that were too long (variable length?) in a varchar(255) field resulted in missing data. As far as I can tell, increasing the size of the field solved the immediate problem. I use the term "immediate" because, as #YvesLeBorg pointed out in the comments, this is bound to fail at some point without input size restrictions on the backend.
Additionally, I couldn't ignore the fact that the PHP/SQL code was wide open to injections.
Passing $mst_customer = trim($_POST['mst_customer']); on to "INSERT INTO ticket_items SET mst_customer = '$mst_customer' and then executing via mysql_query($sql) or die(mysql_error()); is dangerous!
Anybody could write anything in the $_POST parameter and SQL would happily accept it. Prepared statements, PDO, input sanitization etc. are there for a reason.
Finally, there was an issue concerning vanishing + signs in the base64 data. This was the result of missing url encoding of the post data.
I think that sums it up.

Alamofire JSON could not be serialized

I'm trying to make a PHP Post request with Alamofire in my swift app, which has to send SMS with OVH api, but I got an issue :
FAILURE: Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero length.}
I'm not finding how to see echos from the PHP script to solve it. I think that it isn't an Alamofire problem because I make an other request to send emails and it works well. Here is my request where there is the error :
func sendSmsAutoRequest(completionHandler: (responseObject: NSDictionary?, error: NSError?) -> ()) {
let prefs = NSUserDefaults.standardUserDefaults()
let username = prefs.stringForKey(StorageManager.USER_NAME)!
let messageText = prefs.stringForKey(StorageManager.MESSAGE_TEXT)!
let parameters = ["contactsSms": contactsSms, "username": username, "messageText": messageText]
request(.POST, "http://XXX/dontworry/sendAutoSms.php", parameters: (parameters as! [String : AnyObject])).responseJSON { response in
print(response)
}
}
and here is my script :
<?php
require __DIR__ . '/vendor/autoload.php';
use \Ovh\Api;
$applicationKey = "XXX";
$applicationSecret = "XXX";
$consumer_key = "XXX";
$endpoint = "ovh-eu";
$contactsSms = $_POST['contactsSms'];
$userName = $_POST['username'];
$messageText = $_POST['messageText'];
$conn = new Api($applicationKey,
$applicationSecret,
$endpoint,
$consumer_key);
$smsServices = $conn->get('/sms/');
$content = (object) array(
"charset"=> "UTF-8",
"class"=> "phoneDisplay",
"coding"=> "7bit",
"message"=> $messageText,
"noStopClause"=> true,
"priority"=> "high",
"receivers"=> $contactsSms,
"senderForResponse"=> true,
"validityPeriod"=> 2880
);
$resultPostJob = $conn->post('/sms/'. $smsServices[0] . '/jobs/', $content);
$smsJobs = $conn->get('/sms/'. $smsServices[0] . '/jobs/');
echo '{"contacts": $contactsSms,"username": $username, "messageText": $messageText, "result": $resultPostJob, "sms": $smsJobs}'; ?>
EDIT : It seems to work, I don't have the error anymore ! But the SMS is not sent...
From a first reading, your PHP script most probably prints invalid JSON. The following statement will print JSON that contains unquoted strings (assuming one or more of the parameters like $_POST['messsageText'] contain string values):
echo '{"contacts": $contactsSms,"username": $username, "messageText": $messageText, "result": $resultPostJob, "sms": $smsJobs}';
Example output (pretty-printed for readability):
{
"contacts": foobar, # <-- This is invalid! It's a string and needs to be quoted!
"username": johndoe,
"messageText": Hello World, # <-- This is even more invalid!
...
}
I'd suggest to rely on PHP's json_encode function to generate valid JSON output:
echo json_encode([
"contacts" => $contactsSms,
"username" => $username,
"messageText" => $messageText,
// etc.
]);
This was kind of a bug in alamoFire, that was fixed in release 3.1.1, see pull #889, the fixed version works only if your REST like service returns response 204 (NO_RESPONSE) which is in theory the right way to do it.
Serialisation is the process of convert an object to a JSON string. So the problem is not the handling of your response, but that of your request.
Log the contents of your parameters dictionary, and check for nil values.

Parse JSON causes swift dynamic cast failed

The goal is to display a result of json_encode result from php into swift as a label. I have referenced to many tutorials and practices of parsing json with swift, but I still cant understand the issue.
I referenced to an example that uses date.jsontest.com and that works fine.
In my project, I have parsed this simple JSON object to start:
[{"username":"user"}]
Here is the swift code:
override func viewDidLoad() {
super.viewDidLoad()
// 1
//let urlAsString = "http://date.jsontest.com"
let urlAsString = "http://(ip address)/service.php"
let url = NSURL(string: urlAsString)!
let urlSession = NSURLSession.sharedSession()
// 2
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
if (error != nil) {
println(error.localizedDescription)
}
var err: NSError?
// 3
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if (err != nil) {
println("JSON Error \(err!.localizedDescription)")
}
// 4
//let jsonDate: String! = jsonResult["date"] as NSString
//let jsonId = jsonResult["id"] as NSString
//let jsonTime: String! = jsonResult["time"] as NSString
let jsonUser: String! = jsonResult[0] as NSString
dispatch_async(dispatch_get_main_queue(), {
//self.dateLabel.text = jsonId
//self.timeLabel.text = jsonUser
self.dateLabel.text = jsonUser
})
})
// 5
jsonQuery.resume()
//searchItunesFor("JQ Software")
//startConnection()
// Do any additional setup after loading the view, typically from a nib.
}
The code runs fine when I use http://date.jsontest.com as the string along with jsonDate and jsonTime.
I tried to understand the debugger in Xcode, but as a new user to Swift, its hard to understand what the issue is. All I could root out is that there is an issue with how my JSON is formatted.
Any tips are greatly appreciated, thanks.
EDIT:
Here is the code http://(ip address)/service.php that gives me the JSON
<?php
//connect to MySQL
// Create connection
$con=mysqli_connect($hostname,$username,$password,$database);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// This SQL statement selects ALL from the table 'Locations'
$sql = "SELECT username FROM members WHERE id = 1";
// Check if there are results
if ($result = mysqli_query($con, $sql))
{
// If so, then create a results array and a temporary one
// to hold the data
$resultArray = array();
$tempArray = array();
// Loop through each row in the result set
while($row = $result->fetch_object())
{
// Add each row into our results array
$tempArray = $row;
array_push($resultArray, $tempArray);
}
// Finally, encode the array to JSON and output the results
echo json_encode($resultArray);
}
// Close connections
mysqli_close($con);
?>

How to handle PHP errors in Swift

I'm using PHP & JSON to extract some data from a database.
This is my PHP file
<?php
error_reporting(0);
ini_set('error_reporting', E_ALL);
ini_set('display_errors','Off');
$mysqli = new mysqli("localhost", "root", $_REQUEST['password'], "");
if ($mysqli->connect_errno) {
echo "Failed to connect to DB.";
die();
} else {
$dbs = array();
$res = $mysqli->query("SHOW DATABASES");
$res->data_seek(0);
if ($res->num_rows > 0) {
while($row = $res->fetch_assoc()) {
$dbs[] = $row;
}
echo json_encode($dbs);
} else {
echo "Failed to get list of databases from server.";
die();
}} ?>
If the password is wrong, then the system outputs "Failed to connect to DB"
In my program, I have things to handle errors, but I am stuck at one part.
let urlString = "http://\(hostTextField.text):\(portTextField.text)/dblist.php? &password=\(passTextField.text)"
let url: NSURL = NSURL(string: urlString)!
let urlSession = NSURLSession.sharedSession()
println(url)
println(urlSession)
//2
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
println(response)
println(data)
if (error != nil) {
println("Can't connect using credentials")
dispatch_async(dispatch_get_main_queue(), {
HUDController.sharedController.hide(afterDelay: 0.1)
})
sleep(1)
var refreshAlert = UIAlertController(title: "Camaleon Reports", message: "Can't connect to the database", preferredStyle: UIAlertControllerStyle.Alert)
refreshAlert.addAction(UIAlertAction(title: "Retry", style: .Default, handler: { (action: UIAlertAction!) in
println("Yes Logic")
}))
self.presentViewController(refreshAlert, animated: true, completion: nil)
return }
var err: NSError?
var jsonResult: [Dictionary<String, String>] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as [Dictionary<String, String>]
// 3
if (err != nil) {
println("Still cant connect....")
println("JSON Error \(err!.localizedDescription)")
}
var jsonDB : [Dictionary<String, String>] = jsonResult
for currentDictionary in jsonDB{
var currentEntry = currentDictionary["Database"] as String!
My program crashes if I don't have the right password, but have the right IP address and Port/User for the MYSQL Database.
It crashes with this:
fatal error: unexpectedly found nil while unwrapping an Optional value
and points towards jsonResult. It makes sense, cause I don't retrieve two strings.
My problem is that if my password is off, then my PHP file echoes a string. How can I search for that string so that I can use an if statement and stop my application from crashing?
Your problem is likely in this line (wrapped for clarity):
var jsonResult: [Dictionary<String, String>] =
NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.MutableContainers,
error: &err) as [Dictionary<String, String>]
When your PHP script reports the error by just returning the string, it has returned invalid JSON. When you use NSJSONSerialization.JSONObjectWithData to parse it, that method will return nil if the JSON is invalid, as yours is.
You then take that value and assign it to a Swift variable that you've declared is not an optional. Trying to assign nil to a variable not declared with either ? or ! is a runtime error in Swift. (You don't get an error at compile time because you're using as to cast the value.)
One way to fix this would be to change your PHP so the error is proper JSON:
echo "{ \"error\": \"Failed to connect to DB.\" }"; # or something, my PHP is rusty
But that still leaves your Swift program in a fragile state; getting anything but proper JSON back from the server will make it crash.
Better is to declare the jsonResult variable as being an optional:
var jsonResult: [Dictionary<String, String>]? =
NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.MutableContainers,
error: &err) as [Dictionary<String, String>]?
Then in your code you can explicitly check whether jsonResult is nil, and if it is, you know an error has occurred, and can go back and look at the data object to see what it was.
Even that, though, can leave you in trouble. The root of a JSON document doesn't have to be a dictionary; it could be an array. And even if it is a dictionary, the values may not all be strings; they could be numbers, booleans, or nested arrays or dictionaries!
Objective-C's relatively lax type checking makes this easy to deal with, but Swift is stricter. Best might be to use one of the Swift-specific JSON libraries. That'll make your code far more robust.
Good luck!
There are two issues. One is the PHP and one is the Swift.
Your PHP really should never just report an error message. I'd suggest that it always return JSON. This will make it easier for your client code to detect and handle errors appropriately.
<?php
header("Content-Type: application/json");
$response = array();
error_reporting(0);
ini_set('error_reporting', E_ALL);
ini_set('display_errors','Off');
if (!isset($_REQUEST['password'])) {
$response["success"] = false;
$response["error_code"] = 1;
$response["error_message"] = "No password provided";
echo json_encode($response);
exit();
}
$mysqli = new mysqli("localhost", "root", $_REQUEST['password'], "");
if ($mysqli->connect_errno) {
$response["success"] = false;
$response["error_code"] = 2;
$response["mysql_error_code"] = $mysqli->connect_errno;
$response["error_message"] = $mysqli->connect_error;
echo json_encode($response);
exit();
}
if ($res = $mysqli->query("SHOW DATABASES")) {
$dbs = array();
$res->data_seek(0);
if ($res->num_rows > 0) {
while($row = $res->fetch_assoc()) {
$dbs[] = $row;
}
$response["success"] = true;
$response["results"] = $dbs;
} else {
$response["success"] = false;
$response["error_code"] = 3;
$response["error_message"] = "Failed to get list of databases from server.";
}
$res->close();
} else {
$response["success"] = false;
$response["error_code"] = 4;
$response["mysql_error_code"] = $mysqli->errno;
$response["error_message"] = $mysqli->error;
}
$mysqli->close();
echo json_encode($response);
?>
Note, this:
Specifies application/json header for Content-Type;
Always returns a dictionary, containing
a "success" key, which is either true or false;
if an error, an error_code indicating the type of error (1 = no password provided; 2 = connect failed; 3 = no databases found; 4 = some SQL error);
if an error, an error_msg string indicating the error message string; and
if a success, a results array (much like you used to return at the root level).
On the Swift side, you need to :
Change it to look for these various server app-level errors (note, I make the top level structure a dictionary, and your original array of dictionaries a particular value;
You might want to proactively check the statusCode of the response object, to make sure the server gave you a 200 return code (e.g. 404 means that the page was not found, etc.);
You might also want to check for JSON parsing errors (in case some bug in the server prevented well-formed JSON from being returned); and
You really should be percent-escaping the password (because if it included + or & characters, it wouldn't get transmitted successfully otherwise).
Thus, you might have something like:
let encodedPassword = password.stringByAddingPercentEncodingForURLQueryValue()!
let body = "password=\(encodedPassword)"
let request = NSMutableURLRequest(URL: URL!)
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)!
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
// detect fundamental network error
guard error == nil && data != nil else {
print("network error: \(error)")
return
}
// detect fundamental server errors
if let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode != 200 {
// some server error
print("status code was \(httpResponse.statusCode); not 200")
return
}
// detect parsing errors
guard let responseObject = try? NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String : AnyObject] else {
// some problem parsing the JSON response
print(String(data: data!, encoding: NSUTF8StringEncoding))
return
}
// now parse app-level response to make sure `status` was `true`
guard let success = responseObject!["success"] as? NSNumber else {
print("Problem extracting the `success` value") // we should never get here
return
}
if !success.boolValue {
print("server reported error")
if let errorCode = responseObject!["error_code"] as? NSNumber {
switch (errorCode.integerValue) {
case 1:
print("No password provided")
case 2:
print("Connection failed; probably bad password")
case 3:
print("No databases found")
case 4:
print("Some SQL error")
default:
print("Unknown error code: \(errorCode)") // should never get here
}
}
if let errorMessage = responseObject!["error_message"] as? String {
print(" message=\(errorMessage)")
}
return
}
if let databases = responseObject!["results"] as? [[String : AnyObject]] {
print("databases = \(databases)")
}
}
task.resume()
The percent-escaping code is in a String category:
extension String {
// see RFC 3986
func stringByAddingPercentEncodingForURLQueryValue() -> String? {
let characterSet = NSCharacterSet(charactersInString:"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~")
return self.stringByAddingPercentEncodingWithAllowedCharacters(characterSet)
}
}
A couple of other ancillary observations:
Never send a passwords in the clear. Put them in the body of a POST request (not the URL), and then use a https URL.
I'd personally not use the MySQL password part of the app-level authentication. I'd keep MySQL authentication logic encoded on the server-side, and then use your own user authentication table.

Categories