如何验证php中的发布请求

问题描述:

我正在尝试实现HTTP发布验证,其中提到了此文档https://www.clearslide.com/view/mail?iID=YS7LCS8XDPCABFR453DE,我无法理解我到底需要做什么来获得此工作,我试图转储$ _REQUEST$ _SERVER变量。如何验证php中的发布请求

这是输出我得到这个$ _REQUEST

Array 
(
    [emailpitchsent] => 
) 

而且这个输出$ _ SERVER

Array 
(
    [HTTP_HMAC] => D4L1ICmRMii32PdCryBkpSNdxY5XDxC_OXsDTEucyzU 
    [HTTP_DATE] => Thu, 12 Nov 2015 00:50:05 PST 
    [HTTP_SHA1] => GTRFkX7JYVtDQgvrQeXJmHaCF24= 
    [CONTENT_LENGTH] => 262 
    [CONTENT_TYPE] => application/json; charset=UTF-8 
    [HTTP_HOST] => myhost.com 
    [HTTP_CONNECTION] => Keep-Alive 
    [HTTP_USER_AGENT] => Apache-HttpClient/4.5.1 (Java/1.7.0_55) 
    [PATH] => /sbin:/usr/sbin:/bin:/usr/bin 
    [SERVER_SIGNATURE] => <address>Apache/2.2.31 (Amazon) Server at myhost.com Port 80</address> 

    [SERVER_SOFTWARE] => Apache/2.2.31 (Amazon) 
    [SERVER_NAME] => myhost.com 
    [SERVER_ADDR] => 0.0.0.0 
    [SERVER_PORT] => 80 
    [REMOTE_ADDR] => 0.0.0.1 
    [DOCUMENT_ROOT] => /var/www/vhosts/myhost.com/httpdocs 
    [SERVER_ADMIN] => [email protected] 
    [SCRIPT_FILENAME] => /var/www/vhosts/myhost.com/httpdocs/clearslide.php 
    [REMOTE_PORT] => 47400 
    [GATEWAY_INTERFACE] => CGI/1.1 
    [SERVER_PROTOCOL] => HTTP/1.1 
    [REQUEST_METHOD] => POST 
    [QUERY_STRING] => emailpitchsent 
    [REQUEST_URI] => /clearslide.php?emailpitchsent 
    [SCRIPT_NAME] => /clearslide.php 
    [PHP_SELF] => /clearslide.php 
    [REQUEST_TIME] => 1447318205 
) 

这我clearslide.php的内容

<?php 
$req_dump = print_r($_REQUEST, TRUE); 
$ser_dump = print_r($_SERVER,TRUE); 
$fp = fopen('request.log', 'a'); 
fwrite($fp, $req_dump); 
fwrite($fp, $ser_dump); 
fclose($fp); 

我现在要做的事情是让这个事情起作用,我如何验证这个请求并获取数据?

感谢

您可以file_get_contents('php://input')$HTTP_RAW_POST_DATA获取原始的JSON体。以下是如何从头文件验证签名的示例。另外,这里有一个脚本可以生成一个假测试请求。让我知道你是否有更多的麻烦。 :)

验证签名

<?php 
// https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/util/Base64#encodeBase64URLSafeString(byte[]) 
function urlsafe_b64encode($string) { 
    $data = base64_encode($string); 
    $data = str_replace(array('+','/', '='), array('-','_',''), $data);  
    return $data; 
} 

function extract_message(){ 
    $verb = $_SERVER["REQUEST_METHOD"]; 
    $sha1 = $_SERVER["HTTP_SHA1"]; 
    $content_type = $_SERVER["CONTENT_TYPE"]; 
    $request_time = $_SERVER["HTTP_DATE"]; 
    $path = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);  
    return "$verb\n$sha1\n$content_type\n$request_time\n$path"; 
} 

function calculate_signature($to_sign, $api_key) { 
    return urlsafe_b64encode(hash_hmac('sha256', $to_sign, $api_key, true)); 
} 

function get_recieved_signature() { return $_SERVER["HTTP_HMAC"]; } 

function verify_signature($recieved, $calculated) { return $recieved == $calculated; } 

$api_key = "apikey"; 

$to_sign = extract_message(); 
$calculated_signature = calculate_signature($to_sign, $api_key); 
$recieved_signature = get_recieved_signature(); 
$matched = verify_signature($recieved_signature, $calculated_signature); 

$json_obj = json_decode(file_get_contents('php://input'), TRUE); 

$fp = fopen('request.log', 'a'); 
fwrite($fp, print_r(array(
    '$_SERVER' => $_SERVER, 
    "JSON" => $json_obj, 
    "SIGNATURE INFO" => array(
    "To Sign" => str_replace("\n", "\\n", $to_sign), 
    "Received" => $recieved_signature, 
    "Calculated" => $calculated_signature, 
    "Matched" => $matched ? "TRUE" : "FALSE" 
) 
), TRUE)); 
fclose($fp); 

使一个样品请求

<?php 
// https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/util/Base64#encodeBase64URLSafe(byte[]) 
function urlsafe_b64encode($string) { 
    $data = base64_encode($string); 
    $data = str_replace(array('+','/','='), array('-','_',''), $data); 
    return $data; 
} 

$sample_json = '{"company":"Example, Inc","pitchDetailsLink":"https://dev.clearslideng.com/manage/email/details?userVID=6YSZ9BBJWVM3H87PUAPE","senderEmail":"[email protected]","time":"Fri, 11/13/2015, 10:19 AM PST","recipients":["[email protected]"],"decks":["testing"]}'; 

$api_endpoint = 'http://localhost'; 

$verb = "POST"; 
$sha1 = base64_encode(sha1($sample_json)); 
$content_type = "application/json; charset=UTF-8"; 
$request_time = date("D, d M Y H:i:s T"); 
$path = "/emailpitchsent"; 

$to_sign = "$verb\n$sha1\n$content_type\n$request_time\n$path"; 
$api_key = "apikey"; 
$signature = urlsafe_b64encode(hash_hmac('sha256', $to_sign, $api_key, true)); 

$ch = curl_init("$api_endpoint$path"); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
// curl_setopt($ch, CURLOPT_VERBOSE, 1); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"CONTENT-TYPE: $content_type", 
"HMAC: $signature", 
"DATE: $request_time", 
"SHA1: $sha1" 
)); 
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_json); 
$result = curl_exec($ch); 
curl_close($ch); 

echo "To Sign: ". str_replace("\n", "\\n", $to_sign) ."\n\n"; 
echo "Response: \n\n$result"; 

例日志

Array 
(
    [$_SERVER] => Array 
     (
      [USER] => vagrant 
      [HOME] => /home/vagrant 
      [FCGI_ROLE] => RESPONDER 
      [QUERY_STRING] => event=emailpitchsent 
      [REQUEST_METHOD] => POST 
      [CONTENT_TYPE] => application/json; charset=UTF-8 
      [CONTENT_LENGTH] => 270 
      [SCRIPT_FILENAME] => /vagrant/public/index.php 
      [SCRIPT_NAME] => /index.php 
      [REQUEST_URI] => /index.php?event=emailpitchsent 
      [DOCUMENT_URI] => /index.php 
      [DOCUMENT_ROOT] => /vagrant/public 
      [SERVER_PROTOCOL] => HTTP/1.1 
      [GATEWAY_INTERFACE] => CGI/1.1 
      [SERVER_SOFTWARE] => nginx/1.1.19 
      [REMOTE_ADDR] => 10.0.0.10 
      [REMOTE_PORT] => 61094 
      [SERVER_ADDR] => 10.0.0.200 
      [SERVER_PORT] => 80 
      [SERVER_NAME] => 192.168.22.10.xip.io 
      [HTTPS] => off 
      [REDIRECT_STATUS] => 200 
      [LARA_ENV] => local 
      [HTTP_HMAC] => vnQM9g41jE--rJvvwymezRY5VU9pf52Vu9sGhe_Gy-4 
      [HTTP_DATE] => Thu, 19 Nov 2015 06:24:49 PST 
      [HTTP_SHA1] => X7hjTy8DUzIUNO05JiuXp1DT3Js= 
      [HTTP_CONTENT_LENGTH] => 270 
      [HTTP_CONTENT_TYPE] => application/json; charset=UTF-8 
      [HTTP_HOST] => 10.0.0.200 
      [HTTP_CONNECTION] => Keep-Alive 
      [HTTP_USER_AGENT] => Apache-HttpClient/4.5.1 (Java/1.7.0_91) 
      [PHP_SELF] => /index.php 
      [REQUEST_TIME] => 1447943089 
     ) 

    [JSON] => Array 
     (
      [company] => ClearSlide 
      [pitchDetailsLink] => https://dev.clearslideng.com/manage/email/details?userVID=YGCD4WNJT377FQ6FTUFH 
      [senderEmail] => [email protected] 
      [time] => Thu, 11/19/2015, 6:24 AM PST 
      [recipients] => Array 
       (
        [0] => [email protected] 
       ) 

      [decks] => Array 
       (
        [0] => RockyBeach-720 
       ) 

     ) 

    [SIGNATURE INFO] => Array 
     (
      [Path] => /index.php 
      [To Sign] => POST\nX7hjTy8DUzIUNO05JiuXp1DT3Js=\napplication/json; charset=UTF-8\nThu, 19 Nov 2015 06:24:49 PST\n/index.php 
      [Received] => vnQM9g41jE--rJvvwymezRY5VU9pf52Vu9sGhe_Gy-4 
      [Calculated] => vnQM9g41jE--rJvvwymezRY5VU9pf52Vu9sGhe_Gy-4 
      [Matched] => TRUE 
     ) 

) 

示例服务器边toSign

POST 
X7hjTy8DUzIUNO05JiuXp1DT3Js= 
application/json; charset=UTF-8 
Thu, 19 Nov 2015 06:24:49 PST 
/index.php 
+0

非常感谢。 它完美的工作,我能够得到的数据,但我无法验证数据, – Salim

+0

@Salim为了确认,你更新了'$ api_key =“apikey”;'的值以匹配什么时候设置的配置通知端点? –

+0

是的我做了,是的,我可以从本地验证数据,但不是来自ClearSlide,“urlsafe_b64encode(hash_hmac('sha256',$ to_sign,$ api_key,true));” ,他们是否使用SHA的其他变体,而不是sha256,这就是我现在的想法..无论如何感谢的人,:) – Salim

Clearslide.com对所有用户的免费技术支持。您可能想尝试通过[email protected]向他们发送电子邮件 - 他们会很乐意协助安装。