简体   繁体   English

PHP rest API身份验证

[英]PHP rest API authentication

I'm building a restful API for a php application. 我正在为php应用程序构建一个restful API。 At the moment, the API will only accept and respond with json. 目前,API只接受并回复json。 The request, routing and response is all handled by the framework, but I needed to build a custom authentication mechanism. 请求,路由和响应都由框架处理,但我需要构建自定义身份验证机制。

There are two items that I wanted to add in for extra security and to avoid replay attacks: a timestamp and a nonce. 我想添加两个项目以获得额外的安全性并避免重放攻击:时间戳和随机数。

  1. Besides these two items, I wanted a sanity check to ensure that I have not missed anything else really obvious from a security or usability point of view. 除了这两个项目,我还需要进行健全性检查,以确保从安全性或可用性的角度来看,我没有错过任何其他真正明显的东西。
  2. Should the entity_id go in the header instead of the request? entity_id应该在标题而不是请求中吗?

This is what I have for authentication so far: 到目前为止,这是我的身份验证:

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

Example curl request: curl请求示例:

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

hash_hmac() expects its second parameter to be a string, you're passing your decoded JSON object instead. hash_hmac()期望它的第二个参数是一个字符串,而是传递解码的 JSON对象。 Other than that, your approach seems pretty standard. 除此之外,您的方法似乎很标准。 entity_id should also be protected by the HMAC signature, so I'd keep it in the request body or your signature calculation will get a little bit more complicated for no real gain. entity_id也应受到HMAC签名的保护,因此我会将其保留在请求正文中,否则您的签名计算会变得更加复杂,无法获得实际收益。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM