PHP rest API身份验证

时间:2012-09-11 21:15:57

标签: php api rest authentication

我正在为php应用程序构建一个restful API。目前,API只接受并回复json。请求,路由和响应都由框架处理,但我需要构建自定义身份验证机制。

我想添加两个项目以获得额外的安全性并避免重放攻击:时间戳和随机数。

  1. 除了这两个项目之外,我还需要进行健全性检查,以确保从安全性或可用性的角度来看,我没有错过任何其他真正明显的内容。
  2. entity_id应该在标题而不是请求中吗?
  3. 到目前为止,这是我的身份验证:

    function authenticate_request()
    {
        $request = json_decode(file_get_contents('php://input'));
        $request_headers = apache_request_headers();
    
        if ( ! isset($request_headers['X-Auth']) OR ! isset($request_headers['X-Auth-Hash'])) {
            return false;
        }
    
        $user = User::get_by('public_key', $request_headers['X-Auth']);
    
        if ( ! $user) {
            return false;
        }
    
        // every request must contain a valid entity
        if (isset($request->entity_id) && $request->entity_id > 0) {
            $this->entity_id = $request->entity_id;
        } else {
            return false;
        }
    
        $entity = Entity::find($this->entity_id);
        if ( ! $entity) {
            return false;
        }
    
        // validate the hash
        $hash = hash_hmac('sha256', $request, $user->private_key);
    
        if ($hash !== $request_headers['X-Auth-Hash']) {
            return false;
        }
    
        return true;
    }
    

    卷曲请求示例:

    $public_key = '123';
    $private_key = 'abc';
    
    $data = json_encode(array('entity_id' => '3087', 'date_end' => '2012-05-28'));
    $hash = hash_hmac('sha256', $data, $private_key);
    $headers = array(
        'X-Auth: '. $public_key,
        'X-Auth-Hash: '. $hash
    );
    $ch = curl_init('http://localhost/myapp/api/reports/');
    
    curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
    curl_setopt($ch,CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    
    $result = curl_exec($ch);
    curl_close($ch);
    
    print_r($result);
    

1 个答案:

答案 0 :(得分:2)

hash_hmac()期望它的第二个参数是一个字符串,而是传递解码的 JSON对象。除此之外,您的方法似乎很标准。 entity_id也应受到HMAC签名的保护,因此我会将其保留在请求正文中,否则您的签名计算会变得更加复杂,无法获得真正的收益。