I’m using Luracast restler and i’m trying to implement some authentication by implementing iAuthenticate interface.
The thing is, my authentication code needs to query my database to retrieve the user private key. This private key will always be provided in the url request (hashed).
I wanted to open just one database connection to each request, so i need to pass the db connection variable to my class that implements iAuthenticate and to the other classes that handle all the requests. But i can’t figure out how can i pass variables to my class that implements iAuthenticate.
Is it possible?
For reference, here are the luracast examples
thks in advance.
Using Single DB Connection for your API and Authentication Classes
Create a php file called config.php
and place all your db information along with db connection and selection.
For example
<?php
define('DB_SERVER', 'localhost');
define('DB_USER', 'root');
define('DB_PASSWORD', 'password');
define('DB_NAME', 'mysql_db');
//initalize connection to use everywhere
//including auth class and api classes
mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD);
mysql_select_db(DB_NAME);
Include this function using require_once
on both Authentication class and API class, something like (for simplicity I'm not encrypting the password here)
<?php
require_once 'config.php';
class BasicAuthentication implements iAuthenticate{
const REALM = 'Restricted API';
public static $currentUser;
function __isAuthenticated(){
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])){
$user = $_SERVER['PHP_AUTH_USER'];
$pass = $_SERVER['PHP_AUTH_PW'];
$user = mysql_real_escape_string($user);
$pass = mysql_real_escape_string($pass);
mysql_query("UPDATE `login` SET logged=NOW()
WHERE user='$user' AND pass='$pass'");
// echo mysql_affected_rows();
if(mysql_affected_rows()>0){
self::$currentUser = $user;
return TRUE;
}
}
header('WWW-Authenticate: Basic realm="'.self::REALM.'"');
throw new RestException(401, 'Basic Authentication Required');
}
}
Your API class can have a protected method that query the same db, it can be a different table that return the data using the same connection. For simplicity sake I use the same table here.
<?php
require_once 'config.php';
class Simple {
function index() {
return 'public api result';
}
protected function restricted() {
$query = mysql_query("SELECT * FROM login");
$result = array();
while ($row = mysql_fetch_assoc($query)) {
$result[]=$row;
}
return $result;
}
}
Using require_once
makes sure that the php file is included only once on the first encounter. Even if we stop using the auth class latter our api will keep functioning
Assuming that following SQL is used to create our db table
--
-- Database: `mysql_db`
--
--
-- Table structure for table `login`
--
CREATE TABLE IF NOT EXISTS `login` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`logged` datetime DEFAULT NULL,
`user` varchar(10) DEFAULT NULL,
`pass` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `login`
--
INSERT INTO `login` (`id`, `logged`, `user`, `pass`) VALUES
(1, '2011-11-01 22:50:05', 'arul', 'mypass'),
(2, '2011-11-01 23:43:25', 'paulo', 'hispass');
And the index.php with the following
<?php
require_once '../../restler/restler.php';
#set autoloader
#do not use spl_autoload_register with out parameter
#it will disable the autoloading of formats
spl_autoload_register('spl_autoload');
$r = new Restler();
$r->addAPIClass('Simple','');
$r->addAuthenticationClass('BasicAuthentication');
$r->handle();
The Result
if you open index.php/restricted
in the browser and key in the right username and password combination, you will see the following as the result :)
[
{
"id": "1",
"logged": "2011-11-01 22:50:05",
"user": "arul",
"pass": "mypass"
},
{
"id": "2",
"logged": "2011-11-01 23:43:25",
"user": "paulo",
"pass": "hispass"
}
]
Figured it out!
echo mysql_affected_rows();
This line was causing the output to be in text/html format. Commented that out and I was good to go.