I'm building a simple application that requires login. At the moment I'm connecting to my database directly from my C# application however, the college network on which this will be used doesn't allow direct connections to MySQL for some reason. I decided to take a look at how I would do this from PHP instead. I've build a simple login form and tested it and it seems to work. However I have some questions and issues that need sorting out.
How would I first of all stop just anyone typing in the address of the PHP file and getting the data back?
Second, how will I be able to get multiple results back? Let's say I make a PHP file that gets all of the user's files and stores them in the C# application, how do I actually parse this from the PHP file?
Here is an example of a login.php file I would have on the server:
<?php
include("connect.php");
$username = mysql_escape_string($_GET['username']);
$password = mysql_escape_string($_GET['password']);
$squery = mysql_query("SELECT * FROM users WHERE username='$username'");
$query = mysql_fetch_array($squery);
$rowcount = mysql_num_rows($squery);
if($rowcount == 1)
{
if($password != $query['password'])
echo'Password errata';
else
echo 'Login avvenuto';
}
else
echo 'Account non registrato';
?>
And here is the code I'd use on C# to access the PHP file:
string Reply = new WebClient().DownloadString("http://127.0.0.1/ClipCloud.Service/account_auth/login.php?username=" + textBox1.Text + "&password=" + textBox2.Text);
switch (Reply.ToLower())
{
case "account non registrato":
{
MessageBox.Show("Account not registered!");
break;
}
case "password errata":
{
MessageBox.Show("Password error!");
break;
}
case "login avvenuto":
{
MessageBox.Show("Login happened!");
break;
}
default:
{
MessageBox.Show("Error with the remote server, please let try again later!");
break;
}
}
Sorry if this question is a bit confusing, I basically just need to know how to correctly manipulate a database with PHP using C# with correct security in place.
You can get C# communicating with PHP by implementing a simple JSON API Server.
Conside the following : http://yoursite.com/api_server.php
api_server.php
<?php
// Load Request
$api_method = isset($_POST['api_method']) ? $_POST['api_method'] : '';
$api_data = isset($_POST['api_data']) ? $_POST['api_data'] : '';
// Validate Request
if (empty($api_method) || empty($api_data)) {
API_Response(true, 'Invalid Request');
}
if (!function_exists($api_method)) {
API_Response(true, 'API Method Not Implemented');
}
// Call API Method
call_user_func($api_method, $api_data);
/* Helper Function */
function API_Response($isError, $errorMessage, $responseData = '')
{
exit(json_encode(array(
'IsError' => $isError,
'ErrorMessage' => $errorMessage,
'ResponseData' => $responseData
)));
}
/* API Methods */
function loginUser($api_data)
{
// Decode Login Data
$login_data = json_decode($api_data);
// Dummy Check
if ($login_data->username == 'test' &&
$login_data->password == '1234')
{
// Success
API_Response(false, '', 'SUCCESS');
}
else
{
// Error
API_Response(true, 'Invalid username and/or password.');
}
}
?>
Then you communicate with it via C# like this, making POST Requests:
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["api_method"] = "loginUser";
data["api_data"] = "{ \"username\":\"test\", \"password\":\"1234\" }";
var responseBytes = wb.UploadValues(
"http://yoursite.com/api_server.php", "POST", data);
string responseString = Encoding.Default.GetString(responseBytes);
}
Here, the responseString
from the API server will the json string. To decode this, you can use this: http://james.newtonking.com/json
Here's a fully working example of how everything is put together in the C# app using a simple console app:
Note how I am generating json string (for api_data
) via the json library, instead of manually typing it.
using System;
using System.Text;
using System.Net;
using System.Collections.Specialized;
using Newtonsoft.Json;
namespace TemplateFive
{
public class API_Response
{
public bool IsError { get; set; }
public string ErrorMessage { get; set; }
public string ResponseData { get; set; }
}
public class Login_Request
{
public string username { get; set; }
public string password { get; set; }
}
class Program
{
static void Main(string[] args)
{
// request params
string apiUrl = "https://yoursite.com/api_server.php";
string apiMethod = "loginUser";
Login_Request myLogin_Request = new Login_Request()
{
username = "test",
password = "1234"
};
// make http post request
string response = Http.Post(apiUrl, new NameValueCollection()
{
{ "api_method", apiMethod },
{ "api_data", JsonConvert.SerializeObject(myLogin_Request) }
});
// decode json string to dto object
API_Response r =
JsonConvert.DeserializeObject<API_Response>(response);
// check response
if (!r.IsError && r.ResponseData == "SUCCESS")
{
Console.WriteLine("login success");
}
else
{
Console.WriteLine("login error, reason is: {0}",
r.ErrorMessage);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
public static class Http
{
public static String Post(string uri, NameValueCollection pairs)
{
byte[] response = null;
using (WebClient client = new WebClient())
{
response = client.UploadValues(uri, pairs);
}
return Encoding.Default.GetString(response);
}
}
}
finally, to secure the whole thing, run your site under SSL, so you'd access the api server via this URL: https://yoursite.com/api_server.php
Here's me testing the API server locally using a RESTClient pluggin on firefox.