too long

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.