2013-01-22 61 views
7

我正在使用RESTful控制器屬性構建一個使用laravel的RESTful api。到目前爲止,我已經能夠獲得大部分工作。我現在遇到的問題是驗證,我試圖使用「user_id」和「簽名」使用亞馬遜方法。 我使用php的'hash_hmac()'創建簽名。使用laravel進行REST api驗證

此示例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); 
     } 
    } 


} 

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

一個GET請求http://api.xyz.com/v1/tasks/1?user_id=1&sig=41295da38eadfa56189b041a022c6ae0fdcbcd5e65c83f0e9aa0e6fbae666cd8總是偶數返回一個成功的消息時,我改變USER_ID參數的值,其應該使簽名失效並使請求無效。 看來我的verfiy_request方法沒有執行。 請幫我出來

回答

9

我最近也研究這一點,也建議使用過濾器去。它可以工作是這樣的:

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

} 

而在你的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); 
    } 

}); 

另外,感謝我介紹給哨兵:-)

+0

您發送$ SIG和$ userId在請求本身。你不覺得有人可以嗅探這些參數並代表你自己驗證自己嗎? – voila

+0

偉大的問題!是的,你是正確的,這些元素可以被攔截。我認爲亞馬遜會在一段時間後使用某種方法來使URL過期,因爲這個原因。我不一定試圖審查這個人的認證選擇,而是展示如何在Laravel中使用過濾器。 – jonahlyn

2

這是一個快速猜測,我沒有嘗試,但也許你可能想要在調用verify_request之前嘗試添加return語句。

而且你應該看看filters,這將讓你分開您更多的API邏輯和 API認證;-)