2013-01-22 14 views
7

Buduję aplikację RESTful z aplikacją laravel za pomocą właściwości kontrolera RESTful. Do tej pory udało mi się uzyskać większość z nich działa. Problem polega na uwierzytelnianiu, próbuję użyć podejścia Amazon za pomocą "user_id" i "signature". Tworzę podpis za pomocą php 'hash_hmac()'.Autoryzacja REST api z laravelem

kontroler przykładem 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); 
     } 
    } 


} 

a ta klasa kontroler 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); 
     } 
    } 

Making żądanie GET http://api.xyz.com/v1/tasks/1?user_id=1&sig=41295da38eadfa56189b041a022c6ae0fdcbcd5e65c83f0e9aa0e6fbae666cd8 zawsze zwraca komunikat o pomyślnie zakończonej nawet kiedy zmienić wartość parametru user_id, które powinien unieważnić podpis i uczynić żądanie nieważnym. Wygląda na to, że moja metoda verfiy_request nie jest wykonywana. Proszę mi pomóc

Odpowiedz

9

I zostały również badania tego niedawno i polecam również dzieje z filtrami. Może to działać tak:

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

} 

iw swoim routes.php pliku:

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

}); 

Również dzięki za wprowadzenie mnie do Sentry :-)

+0

Wysyłasz $ i $ sig userId w samym żądaniu. Czy nie sądzisz, że ktokolwiek może powąchać te parametry i uwierzytelnić się w twoim imieniu? – voila

+0

Świetne pytanie! I owszem, masz rację, że te elementy mogą zostać przechwycone. Sądzę, że Amazon używa jakiegoś sposobu na wygaśnięcie adresu URL po pewnym czasie z tego powodu. Niekoniecznie próbowałem zbadać wybór uwierzytelniania tej osoby, ale raczej pokazałem, jak używać filtrów w Laravel. – jonahlyn

2

To szybkie przypuszczenie, nie próbowałem, ale może warto spróbować dodać oświadczenie zwrotne przed wywołaniem verify_request.

I należy spojrzeć na filters który pozwoli Ci oddzielić więcej logiki API i api uwierzytelniania ;-)

Powiązane problemy