2013-01-22 43 views
7

Tôi đang xây dựng một api RESTful với laravel bằng cách sử dụng thuộc tính của trình điều khiển RESTful. Cho đến nay tôi đã có thể nhận được hầu hết các hoạt động. Vấn đề hiện tại là việc xác thực, đang cố gắng sử dụng phương pháp tiếp cận Amazon bằng cách sử dụng "user_id" và "signature". Tạo chữ ký bằng cách sử dụng 'hash_hmac()' của php.REST api authenication với laravel

này một ví dụ api khiển

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


} 

và điều này lớp điều khiển 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); 
     } 
    } 

Đưa ra yêu cầu get http://api.xyz.com/v1/tasks/1?user_id=1&sig=41295da38eadfa56189b041a022c6ae0fdcbcd5e65c83f0e9aa0e6fbae666cd8 luôn trả về một thông điệp thành công ngay cả khi tôi thay đổi giá trị của tham số user_id mà nên vô hiệu hóa chữ ký làm cho yêu cầu không hợp lệ. Có vẻ như phương pháp verfiy_request của tôi không thực thi. Hãy giúp tôi ra

Trả lời

9

Tôi cũng đã được nghiên cứu này thời gian gần đây và cũng sẽ khuyên bạn nên đi với các bộ lọc. Nó có thể làm việc gì đó như thế này:

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

} 

Và trong tập tin routes.php của bạn:

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

}); 

Ngoài ra, nhờ sự giới thiệu tôi đến Sentry :-)

+0

Bạn đang gửi $ sig và $ userId trong chính yêu cầu đó. Bạn không nghĩ rằng bất kỳ ai có thể đánh hơi các thông số này và tự xác thực thay mặt bạn? – voila

+0

Câu hỏi hay! Và có bạn là chính xác rằng các yếu tố này có thể bị chặn. Tôi nghĩ rằng Amazon sử dụng một số loại phương pháp để hết hạn URL sau một khoảng thời gian vì lý do này. Tôi không nhất thiết phải xem xét kỹ lưỡng sự lựa chọn xác thực của người này, mà chỉ cho thấy cách sử dụng các bộ lọc trong Laravel. – jonahlyn

2

Đó là một dự đoán nhanh, tôi đã không thử nhưng có thể bạn có thể muốn thêm câu trả lại trước khi gọi verify_request.

Và bạn nên xem xét filters mà sẽ cho phép bạn tách hơn Logic api của bạn và xác thực api ;-)