Page 1 of 1

API Tutorial... Im Stuck

Posted: Sun Jul 24, 2011 3:34 pm
by phpkid01
Hey,
Last night i was working through the API tutorials On Your Youtube Page i recieved no errors when completed everything worked but the purpose of the API seems to be different?? can i use the API to allow External sites to Login with users from my Database using the API, i thought i could so i tried various things Code Below:

api.inc.php
<?php

require("int.php");

//Logs a request.
function log_api_request($ip){
	$ip = mysql_real_escape_string($ip);

	$sql = "INSERT INTO `api_log` (`ip`, `date`, `requests`) VALUES (INET_ATON('{$ip}'), NOW(), 0)
		   ON DUPLICATE KEY UPDATE `requests` = `requests` + 1";

	mysql_query($sql);
}

//Gets the total number of requests that have been made today.
function get_todays_api_requests($ip){
	$ip = mysql_real_escape_string($ip);

	$total = mysql_query("SELECT `requests` FROM `api_log` WHERE `ip` = INET_ATON('{$ip}') AND `date` = DATE(NOW())");

	return (mysql_num_rows($total) == 1) ? mysql_result($toal, 0) : 0;
}

?>
../api.php
<?php

require('class/api.php');


header('Content-type: application/json');

if(isset($_POST['username'])&&isset($_POST['password'])){
	$errors = array();

	$username = (empty($errors)) ? $_SESSION['scmsacc'] = $_POST['username'] : false;

	echo json_encode(array(
			'username'	=> $username,
			'errors'	=> $errors,
		));

	log_api_request($_SERVER['REMOTE_ADDR']);

}else{
	echo json_encode(array(
		'login' => 'Allows Interactivity With The Content Management System to Other Web Systems.',
	));
}

?>
/api_test/api_interface.inc.php:
<?php

class surfcms {
	
	const API_URL = 'http://localhost/projects/surf-cms/api.php';
  // DONT EDIT FROM HERE
	private static function send_post_data($data){
		$url =  parse_url(self::API_URL);
		$boundary = md5(microtime(true));

		$post = '';

		foreach ($data as $name => $value){
			$post .= "--{$boundary}\r\n";
			$post .= "Content-Disposition: form-data; name=\"{$name}\"\r\n\r\n";
			$post .= "{$value}\r\n";
		}

		$post .= "--{$boundary}--\r\n";

		if(isset($url['query'])){
			$head = "POST {$url['path']}?{$url['query']} HTTP:/1.1\r\n";
		}else{
			$head = "POST {$url['path']} HTTP:/1.1\r\n";
		}

		$head .= "Host: {$url['host']}\r\n";
		$head .= "Content-Type: multipart/form-data; boundary=\"{$boundary}\"\r\n";
		$head .= "Content-Length: " . strlen($post) . "\r\n";
		$head .= "Connection: close\r\n\r\n";

		$socket = fsockopen($url['host'], ((isset($url['port'])) ? $url['port'] : 80));

		fwrite($socket, "{$head}{$post}");

		return end(explode("\r\n\r\n", stream_get_contents($socket)));
	}
  //TOO HERE :L <-- the connection is true just passing the username and password is the problem and checking for the result...

	//Grab the Indevidual Content and Put into a $decode->{$varible} but dont know how?
	public static function get_content(){
		return json_decode(self::send_post_data({$GOD_KNOWS}}));
	}

}

?>
/api_test/index.php:
<?php include('api_interface.inc.php'); session_start(); ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
      <head>
             <title></title>
      </head>
      <body>
      	<?php
      	print_r(surfcms::get_contents() . "<br />");
      	?>

      	<form action="" method="POST">
      		Username: <input type="text" name="username" /> <br />
      		Password: <input type="password" name="password" /> <input type="submit" />
      	</form>

      </body>
</html>
Help is Much Apprieciated
phpkid01

Re: API Tutorial... Im Stuck

Posted: Mon Jul 25, 2011 11:29 am
by jacek
You need to add a way for the developer to check a username/password combination to see if it is in your database.

So for example the method for the interface file might look like this
public static function validate_credentials($username, $password){
    $request = array(
        'action'          => 'login',
        'username'     => $username,
        'password'      => sha1($password),
    );

    return json_decode(self::send_post_data($request));
}
The action key here is just do you can check what they are trying to do in api.php and act accordingly.

Re: API Tutorial... Im Stuck

Posted: Tue Jul 26, 2011 3:04 pm
by phpkid01
okay that works like a charm now how would i actually give them the functionality to login on the developers site using the credentials from my database??

/developers_site/api_interface.inc.php:
<?php

class surfcms {
	
	const API_URL = 'http://www.develop.surf-cms.co.uk/api.php';
  // DONT EDIT FROM HERE
	private static function send_post_data($data){
		$url =  parse_url(self::API_URL);
		$boundary = md5(microtime(true));

		$post = '';

		foreach ($data as $name => $value){
			$post .= "--{$boundary}\r\n";
			$post .= "Content-Disposition: form-data; name=\"{$name}\"\r\n\r\n";
			$post .= "{$value}\r\n";
		}

		$post .= "--{$boundary}--\r\n";

		if(isset($url['query'])){
			$head = "POST {$url['path']}?{$url['query']} HTTP:/1.1\r\n";
		}else{
			$head = "POST {$url['path']} HTTP:/1.1\r\n";
		}

		$head .= "Host: {$url['host']}\r\n";
		$head .= "Content-Type: multipart/form-data; boundary=\"{$boundary}\"\r\n";
		$head .= "Content-Length: " . strlen($post) . "\r\n";
		$head .= "Connection: close\r\n\r\n";

		$socket = fsockopen($url['host'], ((isset($url['port'])) ? $url['port'] : 80));

		fwrite($socket, "{$head}{$post}");

		return end(explode("\r\n\r\n", stream_get_contents($socket)));
	}
  //TOO HERE :L <-- the connection is true just passing the username and password is the problem and checking for the result...

	//Grab the Indevidual Content and Put into a $decode->{$varible} but dont know how?
	public static function validate_credentials($username, $password){
    $post_password = sha1(md5(sha1(md5($password))));
        $salt = "SALT";
        $salt_pass = $salt.$post_password.$salt;
	$request = array(
        'action'          => 'login',
        'username'     => $username,
        'password'      => $salt_pass,
    );

    return json_decode(self::send_post_data($request));
}

}

?>
/mysite/api.php:
<?php

require('class/api.php');
session_start();

header('Content-type: application/json');

if(isset($_POST['username'])&&isset($_POST['password'])){
	$errors = array();
	
	$login = sprintf("SELECT * FROM users WHERE username='%s' AND password='%s'", mysql_real_escape_string($post_username), mysql_real_escape_string($salt_pass));
    $rowcount = mysql_num_rows(mysql_query($login));
    if ($rowcount==1){
		$username = (empty($errors)) ? $_SESSION['scmsacc'] = $_POST['username'] : false;
		$session = "1";
    }else{
		$errors[] = "Username / Password Does not exist!";
		$session = "0";
	}
	
	echo json_encode(array(
			'username'	=> $username,
			'session' 	=> $session,
			'errors'	=> $errors,
		));

	log_api_request($_SERVER['REMOTE_ADDR']);

}else{
	echo json_encode(array(
		'login' => 'Allows Interactivity With The Content Management System to Other Web Systems.',
	));
}

?>

live testing here: http://api.test.develop.surf-cms.co.uk/
username: james
pass: gardner1

Re: API Tutorial... Im Stuck

Posted: Tue Jul 26, 2011 8:20 pm
by jacek
That query should really be done by a function ;)

To have them be able to log in on the developers site you need to do what ever means they are logged in, so in my tutorial I set $_SESSION['username'] when they entered the password correctly and then the fact that that was set meant they were logged in.

It looks like you have a way to check if what they entered was the correct information so just add these two things together ;)

Re: API Tutorial... Im Stuck

Posted: Tue Jul 26, 2011 8:56 pm
by phpkid01
i dont understand how i could set the session over JSON.. thats why i set the variable $session and included it in the /mysite/api.php and sent it to the developers site... but it doesnt seem to work... i mean the query there is no errors displayed??

phpkid

Re: API Tutorial... Im Stuck

Posted: Tue Jul 26, 2011 10:02 pm
by jacek
You don't, you set the session as you would normally and just use the API to see if the password they gave was valid.
if (surfcms::valid_credentials($_POST['uasername'], $_POST['password']) === false){
    $errors[] = 'You entered the wrong username / password.';
}

// more error checking...

if (empty($errors)){
    $_SESSION['username'] = $_POST['username'];
}
Then on pages
if (isset($_SESSION['username'])){
    // they are logged in.
}
Would be the basics of the code.

Re: API Tutorial... Im Stuck

Posted: Tue Jul 26, 2011 10:51 pm
by phpkid01
Okay i got it working with all the validation things but how can i put the array information displayed into variables :?:

ive tried this:
/developers_site/index.php:
<?php
		echo "<pre>";
			$array = surfcms::validate_credentials($_POST['username'], $_POST['password'], $_POST['key']);
			while (list($k, $v)=each($array))
			$$k = $v;
			echo "Session: {$session}";
		echo "</pre>";
      	?>
personally i dont think what is returning isnt a array... would this work or not??

cheers
phpkid1

P.S. http://api.test.develop.surf-cms.co.uk/
username: james
password: gardner1

Re: API Tutorial... Im Stuck

Posted: Wed Jul 27, 2011 1:32 pm
by jacek
You don't really want to create local variable for everything that the API returns.

What are you actually trying to do :?

Re: API Tutorial... Im Stuck

Posted: Wed Jul 27, 2011 2:14 pm
by phpkid01
im trying to return the session variable, and if the session===1 then i want to log the user in... if not add to $errors[] my error message.

but i cannot get the individual params and store them into a variable ...

you get that??

Re: API Tutorial... Im Stuck

Posted: Thu Jul 28, 2011 1:30 pm
by jacek
Okay, well to do that you wan tot do somethign more like this.
$array = surfcms::validate_credentials($_POST['username'], $_POST['password'], $_POST['key']);

if ($array['session'] == 1){
    $_SESSION['username'] = $_POST['username'];
}else{
    // handlet the errors.
}

Re: API Tutorial... Im Stuck

Posted: Thu Jul 28, 2011 5:51 pm
by phpkid01
haha YOU ARE A STAR!!!

THank you soooo much :)

Test it out if you want:
http://www.api.test.develop.surf-cms.co.uk/
username: james
password: gardner1

Re: API Tutorial... Im Stuck

Posted: Sat Jul 30, 2011 11:07 am
by Torniquet
Just a word of warning on this if i may...


I have been planning out a similar thing for my website.

I would run everything through a javascript file which posts the information directly to your website. giving the end user the option to post these details to their own site before getting it validated through the plugin could cause a huge security risk as there is nothing stopping the end user from dumping the information directly into their own database before it gets sent to you for validation. They then have access to usernames and passwords.

I am yet to start coding and testing such a function, but removing the option to post to the end users site would have to be removed.

Whether it is going to work how i plan it to work is yet to be found out lol... but the theory is there :) lol