I am building a RESTful api with laravel using the RESTful controller property. So far i've been able to get most of it working. The issue am having now is authenication, am trying to use Amazon approach using a "user_id" and "signature". Am creating the signature using php's 'hash_hmac()'.
this an example api controller
class Api_Tasks_Controller extends Api_Controller {
public $restful = true;
public function get_index($id = null) {
$this->verfiy_request();
if(!is_null($id))
{
return Response::json(array("tasks"=>"just one"),200);
}
else
{
return Response::json(array("tasks"=>"everthing"),200);
}
}
}
and this the api controller class
class Api_Controller extends Controller {
public function verify_request() {
//user id
$user_id = (int) Input::get('user_id');
//signature
$sig = Input::get('sig');
//Lookup user
$user = Sentry::user($user_id);
if($user) {
//user email
$email = $user->email;
//user api key
$api_key = $user->metadata['api_key'];
//recreate signature
$_sig = hash_hmac("sha256",$email.$user_id,$api_key);
if($_sig === $sig) {
return Response::json(array("message"=>"Request Ok"),200);
}
else {
return Response::json(array("message"=>"Request Bad"),400);
}
}
else {
return Response::json(array("message"=>"Request not authorized"),401);
}
}
Making a get request http://api.xyz.com/v1/tasks/1?user_id=1&sig=41295da38eadfa56189b041a022c6ae0fdcbcd5e65c83f0e9aa0e6fbae666cd8
always returns a successful message even when i alter the value of the user_id parameter which should void the signature an make the request invalid.
It seems my verfiy_request
method is not executing.
Please help me out
I have also been researching this recently and would also recommend going with filters. It could work something like this:
class Api_Tasks_Controller extends Base_Controller {
public $restful = true;
function __construct() {
// Check if user is authorized
$this->filter('before', 'api_checkauth');
}
// rest of the class ....
}
And in your routes.php file:
Route::filter('api_checkauth', function()
{
//user id
$user_id = (int) Input::get('user_id');
//signature
$sig = Input::get('sig');
try {
//Lookup user
$user = Sentry::user($user_id);
if($user) {
//user email
$email = $user->email;
//user api key
$api_key = $user->metadata['api_key'];
//recreate signature
$_sig = hash_hmac("sha256",$email.$user_id,$api_key);
if($_sig === $sig) {
return Response::json(array("message"=>"Request Ok"),200);
}
else {
return Response::json(array("message"=>"Request Bad"),400);
}
}
else {
return Response::json(array("message"=>"Request not authorized"),401);
}
}
catch (Sentry\SentryException $e) {
$errors = $e->getMessage(); // catch errors such as user not existing or bad fields
return Response::json(array("message"=>$errors),404);
}
});
Also, thanks for introducing me to Sentry :-)
It's a quick guess, I didn't try but maybe you might want to try to add a return statement before calling verify_request.
And you should look into filters which will allow you to separate more your api logic and api authentication ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With