2013-01-22 22 views
7

Sto costruendo una API RESTful con laravel usando la proprietà del controller RESTful. Fino ad ora sono riuscito a far funzionare la maggior parte di esso. Il problema sta avendo ora è authenicazione, sto cercando di utilizzare l'approccio di Amazon utilizzando un "user_id" e "firma". Sto creando la firma usando 'hash_hmac()' di php.REST api authenication con laravel

questo regolatore un esempio api

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); 
     } 
    } 


} 

e questa classe il controller api

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); 
     } 
    } 

Effettuare una richiesta GET http://api.xyz.com/v1/tasks/1?user_id=1&sig=41295da38eadfa56189b041a022c6ae0fdcbcd5e65c83f0e9aa0e6fbae666cd8 restituisce sempre un messaggio di successo anche quando ho alterare il valore del parametro user_id che dovrebbe annullare la firma e rendere la richiesta non valida. Sembra che il mio metodo verfiy_request non sia in esecuzione. Please help me

risposta

9

Sono stato anche occupando di recente e consiglio anche di andare con i filtri. Potrebbe funzionare qualcosa di simile:

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 .... 

} 

E nel file routes.php:

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); 
    } 

}); 

Inoltre, grazie per l'introduzione di me di Sentry :-)

+0

Stai inviando $ sig e $ userId nella richiesta stessa. Non pensi che nessuno possa annusare questi parametri e autenticarsi a tuo nome? – voila

+0

Ottima domanda! E sì, hai ragione che questi elementi possono essere intercettati. Penso che Amazon usi una sorta di metodo per scadere l'URL dopo un periodo di tempo per questo motivo. Non stavo necessariamente cercando di scrutare la scelta dell'autenticazione di questa persona, ma piuttosto di mostrare come usare i filtri in Laravel. – jonahlyn

2

È una rapida ipotesi, non ho provato ma forse potresti voler provare ad aggiungere un'istruzione return prima di chiamare verify_request.

E si dovrebbe guardare in filters che vi permetterà di separare più la logica di api e api autenticazione ;-)