-3

我有下面用 Ruby 编写的脚本。我想知道是否有人可以帮助我将其转换为 PHP。我知道这是一个很大的问题。我希望将 ruby​​ 脚本转换为 PHP curl 请求。

请参阅文档链接https://www.sinch.com/docs/rest-apis/api-documentation/#applicationsignedrequest

第一个代码是 SAMPLE ruby​​ 脚本。虽然下面的第二个是我自己尝试用 PHP 编写的。没有成功,因为我得到“无效的签名错误”。

require "base64"
require "openssl"
require "time"
require "net/http"
require "uri"
require "json"

to = "+4412345678"
message = "Test sms message"
key = "wwwwwwwwwxxxxxxxx" //Key as supplied by sinch.com
secret = "zzzzzzzyyyyyyyyy" // Secret as supplied by sinch.com

body = "{\"message\":\"" + message + "\"}"
timestamp = Time.now.iso8601
http_verb = "POST"
path = "/v1/sms/" + to
scheme = "Application"
content_type = "application/json"
digest = OpenSSL::Digest.new('sha256')
canonicalized_headers = "x-timestamp:" + timestamp
content_md5 = Base64.encode64(Digest::MD5.digest(body.encode("UTF-8"))).strip
string_to_sign = http_verb + "\n" + content_md5 + "\n" + content_type + "\n" + canonicalized_headers + "\n" + path        
signature = Base64.encode64(OpenSSL::HMAC.digest(digest, Base64.decode64(secret), string_to_sign.encode("UTF-8"))).strip
authorization = "Application " + key + ":" + signature

uri = URI.parse("https://messagingApi.sinch.com" + path)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
headers = {"content-type" => "application/json", "x-timestamp" => timestamp, "authorization" => authorization}
request = Net::HTTP::Post.new(uri.request_uri)
request.initialize_http_header(headers)
request.body = body
puts JSON.parse(http.request(request).body)

下面是我的脚本,我可以毫无问题地接受一个全新的脚本。我是超级红宝石新手。请帮忙。

$to="+4412345678";
$text="Hello there test message";
$curl_post_data = array(
    'Message' => $text
);

$curl_post_data=json_encode($curl_post_data);

$timestamp=date("c");
$key = "wwwwwwwwwwwxxxxxxxxxxx";
$secret = "zzzzzzzzzzzzyyyyyyyyyyy";
$http_verb="POST";
$path = "/v1/sms/".$to."";
$scheme = "Application ";
$content_type = "application/json";
$canonicalized_headers = "x-timestamp:".$timestamp."";
$content_md5=base64_encode( md5($curl_post_data,true) );
$string_to_sign = array(
'http_verb' => $http_verb, 
'content_md5' => $content_md5,
'content_type' => $content_type,
'canonicalized_headers' =>$canonicalized_headers
);      
$signature = hash_hmac("sha256", $secret,json_encode($string_to_sign));
$authorization = "".$scheme."".$key.":".$signature."";

$service_url = 'https://messagingapi.sinch.com/v1/sms/'.$to.'';
$curl = curl_init($service_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=UTF-8', 'x-timestamp: '.$timestamp.'','authorization: '.$authorization.''));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$curl_response = curl_exec($curl);
$response = json_decode($curl_response);
curl_close($curl);

var_dump($response);

?>

任何帮助都可以,每当遇到问题时,Stackoverflow 都是一个有用的资源,我希望我的问题也能帮助其他人。

4

2 回答 2

1

我让它工作,不得不重写一些东西。无论如何,这是一个适用于任何可能需要它的人的工作代码。

<?php

$to="+4412345678";
$text2="Test sms message from PHP";
$curl_post_data = array(
    'message' => $text2
);

$timestamp=date("c");
$key = "wwwwwwwwwwwwwxxxxxxxxxxxxxxx";
$secret ="zzzzzzzzzzzzyyyyyyyyyyyyyy";
$http_verb="POST";
$path = "/v1/sms/".$to."";
$scheme = "Application";
$content_type = "application/json";
$canonicalized_headers = "x-timestamp:".$timestamp."";

$content_md5=md5(json_encode($curl_post_data),true);

$string_to_sign ="".$http_verb."\n".$content_md5."\n".$content_type."\n".$canonicalized_headers."\n".$path."\n";    

$signature = hash_hmac("sha256", base64_encode($secret),utf8_encode($string_to_sign) true);
$signature=base64_encode($signature);
$authorization = "".$scheme."".$key.":".$signature."";


$curl_post_data=json_encode($curl_post_data);
$service_url = 'https://messagingapi.sinch.com/v1/sms/'.$to.'';
$curl = curl_init($service_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=UTF-8','x-timestamp:'.$timestamp.'','authorization:'.$authorization.''));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$curl_response = curl_exec($curl);
$response = json_decode($curl_response);
curl_close($curl);
var_dump($response);
?>
于 2015-02-17T14:48:52.157 回答
0

Completely working code. Also, thanks to 'Stephen' for basical porting from Ruby to PHP. It saves me a lot of time. Some notes:

  • Key should be copied from apps menu of sinch account as is (without any conversion)
  • String to sign shouldn't contain new line at the end. Also, please check every changes by setting default values from commented code.
  • In the PHP hash_hmac function cody should be defined before secret (in Ruby arguments should be defined in other order)
  • If actual headers will contain charset definition - string_to_sign should contain it too. I have deleted them at all.

    $key     = 'key';
    $secret  = 'secret';
    $message = 'your message';
    $phone   = '+000000000000';
    
    $body = json_encode(array('message'=>$message));
    $timestamp = date("c");
    
    // {{{ test values for checking code (from docs)
    /*
        $phone="+46700000000";
        $key = "5F5C418A0F914BBC8234A9BF5EDDAD97";
        $secret ="JViE5vDor0Sw3WllZka15Q==";
        $timestamp='2014-06-04T13:41:58Z';
        $body = '{"message":"Hello world"}';
    */
    // result:
    //      content-md5 should be 'jANzQ+rgAHyf1MWQFSwvYw=='
    //      signature should be 'qDXMwzfaxCRS849c/2R0hg0nphgdHciTo7OdM6MsdnM='
    // }}}
    
    $path                  = "/v1/sms/" . $phone;
    $content_type          = "application/json";
    $canonicalized_headers = "x-timestamp:" . $timestamp;
    
    $content_md5 = base64_encode( md5( utf8_encode($body), true ));
    
    $string_to_sign =
        "POST\n".
        $content_md5."\n".
        $content_type."\n".
        $canonicalized_headers."\n".
        $path;
    
    $signature = base64_encode(hash_hmac("sha256", utf8_encode($string_to_sign), base64_decode($secret), true));
    $authorization = "Application " . $key . ":" . $signature;
    
    $curl_post_data=json_encode($curl_post_data);
    $service_url = 'https://messagingapi.sinch.com'.$path;
    $curl = curl_init($service_url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'content-type: '.$content_type,
        'x-timestamp:' . $timestamp,
        'authorization:' . $authorization
    ));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $curl_response = curl_exec($curl);
    // @todo: checking response / working with results
    curl_close($curl);
    
于 2015-07-13T08:49:47.230 回答