【问题标题】:REST api authenication with laravel使用 laravel 进行 REST api 身份验证
【发布时间】:2013-01-05 19:54:16
【问题描述】:

我正在使用 RESTful 控制器属性构建一个带有 laravel 的 RESTful api。到目前为止,我已经能够让它大部分工作。现在遇到的问题是身份验证,我正在尝试使用“user_id”和“签名”的亚马逊方法。 我正在使用 php 的“hash_hmac()”创建签名。

这是一个示例 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 方法没有执行。 请帮帮我

【问题讨论】:

    标签: php rest authentication laravel


    【解决方案1】:

    我最近也在研究这个,也建议使用过滤器。它可以像这样工作:

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

    另外,感谢您向我介绍 Sentry :-)

    【讨论】:

    • 您在请求本身中发送 $sig 和 $userId。您不认为任何人都可以嗅探这些参数并代表您进行身份验证吗??
    • 好问题!是的,您是正确的,这些元素可以被拦截。由于这个原因,我认为亚马逊使用某种方法在一段时间后使 URL 过期。我不一定要仔细检查此人的身份验证选择,而是展示如何在 Laravel 中使用过滤器。
    【解决方案2】:

    这是一个快速的猜测,我没有尝试,但也许您可能想尝试在调用 verify_request 之前添加一个 return 语句。

    您应该查看filters,这将允许您将更多的 api 逻辑和 api 认证 ;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-29
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      相关资源
      最近更新 更多