【问题标题】:How to handle received HTTP Header如何处理接收到的 HTTP Header
【发布时间】:2016-06-11 19:38:27
【问题描述】:

我的问题是如何使用从其他站点收到的 php 读取标头信息。 (我正在使用 patreon webhook) 文档页面说:

当其中一个事件发生时,我们的服务器将向您指定的 URL 发送 HTTP POST。此 HTTP POST 将包含来自 JSON 格式的用户操作的相关数据。它还将有标题
X-Patreon-Event:<trigger>
X-Patreon-Signature:<message signature>
其中消息签名是使用您的 client_secret 签名的 JSON POST 正文 HMAC(使用 MD5)

这是我的代码:

<?php
logData("asd");
$headers = getallheaders();
$X_Patreon_Event = $headers['X-Patreon-Event'];
$X_Patreon_Signature = $headers['X-Patreon-Signature'];
logMusic(json_decode($X_Patreon_Event));
logMusic(json_decode($X_Patreon_Signature));
function logData($str){
    $url = '/var/www/websitelog.txt';
    $current = "$str\n";
    file_put_contents($url,$current,FILE_APPEND | LOCK_EX);
}

【问题讨论】:

    标签: php http-headers patreon


    【解决方案1】:

    getallheaders(自 PHP 5.4.0 起)会将所有标头作为关联数组返回...

    $headers = getallheaders();
    

    ...然后您将能够检查以获取所需的标头值

    $X_Patreon_Event = $headers['X-Patreon-Event'];
    $X_Patreon_Signature = $headers['X-Patreon-Signature'];
    

    旁注:getallheaders() 功能可能不可用(例如,如果您的网络服务器是 nginx)。在这种情况下,您始终可以使用一小段代码重新实现该功能:Get the http headers from current request in PHP

    【讨论】:

    • 我检查了 javascrip 控制台,它说这个错误:POST https://api.patreon.com/oauth2/webhooks/32/test?json-api-version=1.0 send @ jquery.min.js:2v.extend.ajax @ jquery.min.js:2(anonymous function) @ webhooks:714v.event.dispatch @ jquery.min.js:2o.handle.u @ jquery.min.js:2 webhooks:1 XMLHttpRequest cannot load https://api.patreon.com/oauth2/webhooks/32/test?json-api-version=1.0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.patreon.com' is therefore not allowed access. The response had HTTP status code 500.
    • 这是因为您没有在 AJAX 请求中发送Access-Control-Allow-Origin 标头。这与这个问题无关。
    • 问题是它没有将我发送到页面,因此我无法将其回显,或者当我尝试将其记录到文件中时没有任何反应
    • 你写了 我的问题是如何使用从其他站点收到的 php 读取标题信息 - 如果你的问题不同,那么它应该得到不同的问题。隔离问题,发布代码的相关部分并询问...
    【解决方案2】:


    我有一个使用 php 和 mysqli 的完整工作 webhooks 页面希望这会有所帮助
    注意** 你需要 php 5.6 > 才能工作
    我的实现所需的 mysql 数据库表

    /**

    -- 餐桌顾客的餐桌结构

    CREATE TABLE IF NOT EXISTS patrons (
    patron_key bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'key to row',
    patron_id tinytext NOT NULL COMMENT 'patron id',
    patron_fullname tinytext NOT NULL COMMENT 'fullname',
    patron_firstname tinytext NOT NULL,
    patron_lastname tinytext NOT NULL,
    patron_email tinytext NOT NULL,
    patron_image_url tinytext NOT NULL,
    patron_pledge bigint(20) NOT NULL,
    patron_list tinyint(4) NOT NULL COMMENT 'include in patrons honour list',
    patron_decline tinytext,
    PRIMARY KEY (patron_key)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
    

    -- -- 表格通知的表格结构

    CREATE TABLE IF NOT EXISTS notifications (
    notification_id bigint(20) NOT NULL AUTO_INCREMENT,
    notification_type tinytext NOT NULL,
    notification text NOT NULL,
    notification_action int(11) NOT NULL,
    notification_date tinytext NOT NULL,
    notification_archived tinytext NOT NULL,
    PRIMARY KEY (notification_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1401 ;
    

    */

    $secret_webhook_id = "your-secret-key-here";
    
    /** get the headers */
    $headers = getallheaders();
    $X_Patreon_Event = $headers['X-Patreon-Event'];
    $X_Patreon_Signature = $headers['X-Patreon-Signature'];
    
    /** get the json body */
    $body = @file_get_contents("php://input");
    
    /** get json body as array */
    $patron_data = json_decode($body, true);
    
    /** compute an md5 hash using the body and your secret key */
    $signature = hash_hmac('md5', $body, $secret_webhook_id);
    
    /** Timing attack safe string comparison */
    if (hash_equals ($X_Patreon_Signature, $signature)){
    
    /** get the data from the json array - look for errors*/
    if (isset($patron_data['included']) && isset($patron_data['data'])) {
    $data             = $patron_data['data'];
    $declined         = $data['attributes']['declined_since'];
    
    /** stored as a string*/
    $declined         = is_null($declined) ? "":$declined;
    
    $included         = $patron_data['included'];
    $patron_id        = $included[0]['id'];
    $patron_full_name = $included[0]['attributes']['full_name'];
    $patron_firstname = $included[0]['attributes']['first_name'];
    $patron_lastname  = $included[0]['attributes']['last_name'];
    $patron_email     = $included[0]['attributes']['email'];
    $patron_image_url = $included[0]['attributes']['image_url'];
    $pledge           = $included[1]['attributes']['amount_cents'];
    
    /** select event for db insert/update/delete*/
    switch ($X_Patreon_Event){
        case "pledges:create":
            $sql = "INSERT INTO patrons SET patron_id  = ?, patron_fullname = ?, patron_firstname = ?, patron_lastname = ?, patron_email = ?, patron_image_url = ?, patron_pledge = ?, patron_list = 1, patron_decline = ?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("ssssssis", $patron_id, $patron_full_name, $patron_firstname, $patron_lastname, $patron_email, $patron_image_url, $pledge, $declined);
            if (!$stmt->execute()) {
                /** your_error_routine(__LINE__, __FILE__, $sql, $stmt->error); */
            }
            break;
        case "pledges:update":
            $sql = "UPDATE patrons SET patron_fullname = ?, patron_firstname = ?, patron_lastname = ?, patron_email = ?, patron_image_url = ?, patron_pledge = ?, patron_decline = ? WHERE patron_id = ?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("sssssiss", $patron_full_name, $patron_firstname, $patron_lastname, $patron_email, $patron_image_url, $pledge, $declined, $patron_id);
            if (!$stmt->execute()) {
                /** your_error_routine(__LINE__, __FILE__, $sql, $stmt->error); */
            }
            break;
        case "pledges:delete":
            $sql = "DELETE FROM patrons WHERE patron_id = ?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("s", $patron_id);
            if (!$stmt->execute()) {
                 /** your_error_routine(__LINE__, __FILE__, $sql, $stmt->error); */
            }
            break;
    }
    
    /** now update your own admin notifications */
    $notification = "Patreon Webhook update for: $patron_full_name - X_Patreon_Event: $X_Patreon_Event";
    $sql = "INSERT INTO notifications SET notification_type = 'Patreon', notification = ?, notification_date = ".time();
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $notification);
    if (!$stmt->execute()) {
        /** your_error_routine(__LINE__, __FILE__, $sql, $stmt->error); */
    }
    

    }

    【讨论】:

      【解决方案3】:

      在你的脚本中写:

      var_dump($_SERVER);
      

      你会看到返回的变量。然后,您可以像访问数组一样访问它们。

      正如这里回答的那样,getallheaders() 就是您要查找的内容。

      由于它是 JSON,请在这些变量上使用 json_decode(),阅读有关 json_decode/encode 的手册。

      【讨论】:

      • 唯一的问题是当我测试帖子时它不会重定向到我的页面
      • 什么意思?你试过 var_dump($_SERVER) 吗?
      • OP 需要获取标头响应值而不是 POST 值
      • @Paolo Opps,我的错,我读得太快了,你是对的。但是 $_SERVER 仍然可以工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 2012-12-30
      • 2019-01-17
      • 1970-01-01
      • 2020-12-30
      相关资源
      最近更新 更多