将 PHP Api 调用示例代码转换为带有 OAuth 1.0 的 C# RestSharp Api 调用

Converting PHP Api call example code to a C# RestSharp Api call w/ OAuth 1.0

我正在呼叫第 3 方 API,它为我提供了 PHP 代码示例,说明如何呼叫他们的 API。我不知道 PHP 但它看起来非常简单明了,对我来说可以尝试构建一个类似的 .NET 解决方案。下面的 PHP 示例执行的是 Post,但在我的 C# 示例中,我将执行 Get。我用一些虚拟值模拟了 PHP 示例。

$params = array();
$params['assertion_id'] = "b57936e4-6cea-46f4-a897-c7b3a6f01147"; // Example Assertion ID.
$params['product_id'] = "product001";
$params['product_name'] = "Useless Product";
$params['price'] = "1.99";

// Generate Signature Base String.
$params['api_key'] = "526587410g44p9kk8f7h2bb2zf3365va"; // Example Api Key.
$params['timestamp'] = "1510760624"; // Example Timestamp.
$params['nonce'] = "uilp37xh"; // Example Nonce.
ksort($params);

$url = "https://someurl.com/api/product";
$signature_base_string = 'POST&'.urlencode($url).'&'.http_build_query($params);

// Encrypt signature base string for signature.
$secret_key = "DlKST1adTpoWELS8TjjBc1pFATdlGA8qHUNEaq9MOSAUT648AlAvzK4EEC7="; // Example Secret Key.
$signature = base64_encode(hash_hmac('sha1', $signature_base_string, base64_decode($secret_key), true));
$params['signature'] = $signature;

// Send Request.
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, count($params));
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);

这是我迄今为止使用 RestSharp 构建的 C# 代码示例。随机数、时间戳和签名遵守 OAuth 1.0 规范,但我不确定我是否正确处理了该部分?我无法提供真正的值来实际测试 Api 调用,但我知道代码确实有效,因为它确实从第 3 方 Api 得到了响应。但是,响应指出缺少参数...

public class ProductApiRequest
{
    private string _api;
    private string _apiKey;
    private string _apiSecretKey;

    public ProductApiRequest()
    {
        _api = "https://someurl.com/api/";
        _apiKey = "526587410g44p9kk8f7h2bb2zf3365va";
        _apiSecretKey = "DlKST1adTpoWELS8TjjBc1pFATdlGA8qHUNEaq9MOSAUT648AlAvzK4EEC7=";
    }

    public class Product
    {
        public Guid assertion_id { get; set; }
        public String api_key { get; set; }
        public string product_id { get; set; }
        public string product_name { get; set; }
        public string price { get; set; }
        public string timestamp { get; set; }
        public string nonce { get; set; }
        public string signature { get; set; }
    }

    public string getProduct()
    {
        try
        {
            Product oProduct = new Product();

            oProduct.assertion_id = Guid.NewGuid();
            oProduct.api_key = _apiKey;
            oProduct.product_id = "product001";
            oProduct.product_name = "Useless Product";
            oProduct.price = "1.99";
            oProduct.timestamp = GenerateTimeStamp();
            oProduct.nonce = GenerateNonce();
            oProduct.signature = GenerateSignature(oProduct.nonce, oProduct.timestamp, _apiSecretKey);

            var path = "product";
            dynamic request = new RestSharp.RestRequest(path, RestSharp.Method.GET);
            request.RequestFormat = RestSharp.DataFormat.Json;
            request.JsonSerializer = new RestSharp.Serializers.JsonSerializer();
            request.AddJsonBody(oProduct);

            var client = new RestSharp.RestClient(_api);
            var response = client.Execute(request);

            return "Return something.";
        }
        catch (Exception ex)
        {
            return ex.Message.ToString();
        }
    }

    public string GenerateTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0));
        string timeStamp = ts.TotalSeconds.ToString();
        timeStamp = timeStamp.Substring(0, timeStamp.IndexOf("."));
        return timeStamp;
    }

    public string GenerateNonce()
    {
        var _random = new Random();
        var sb = new StringBuilder();
        for (int i = 0; i < 8; i++)
        {
            int g = _random.Next(3);
            switch (g)
            {
                case 0:
                    // lowercase alpha
                    sb.Append((char)(_random.Next(26) + 97), 1);
                    break;
                default:
                    // numeric digits
                    sb.Append((char)(_random.Next(10) + 48), 1);
                    break;
            }
        }
        return sb.ToString();
    }

    public string GenerateSignature(string nonce, string timestamp, string apisecretkey)
    {
        var encoder = new UTF8Encoding();
        var hasher = new System.Security.Cryptography.HMACSHA1();
        var vals = string.Concat(nonce, timestamp, apisecretkey);
        byte[] hashedDataBytes = hasher.ComputeHash(encoder.GetBytes(vals));
        return Convert.ToBase64String(hashedDataBytes);
    }
}

如果能帮助将 PHP 解决方案转换为 C# 解决方案,我们将不胜感激!

我不知道 PHP 但我设法找到了解决方案! \m/ 金属 \m/

public class ProductApiRequest
{
    private string _api;
    private string _apiKey;
    private string _apiSecretKey;
    private string _resource;

    public ProductApiRequest()
    {
        _api = "https://someurl.com/api/";
        _apiKey = "526587410g44p9kk8f7h2bb2zf3365va";
        _apiSecretKey = "DlKST1adTpoWELS8TjjBc1pFATdlGA8qHUNEaq9MOSAUT648AlAvzK4EEC7=";
        _resource = "products";
    }

    public class Product
    {
        public Guid assertion_id { get; set; }
        public String api_key { get; set; }
        public string product_id { get; set; }
        public string product_name { get; set; }
        public string price { get; set; }
        public string timestamp { get; set; }
        public string nonce { get; set; }
        public string signature { get; set; }
    }

    public string getProduct()
    {
        Product oProduct = new Product();

        oProduct.assertion_id = Guid.NewGuid();
        oProduct.api_key = _apiKey;
        oProduct.product_id = "product001";
        oProduct.product_name = "Useless Product";
        oProduct.price = "1.99";
        oProduct.timestamp = GenerateTimeStamp();
        oProduct.nonce = GenerateNonce();

        // Create Signature Base String.
        string apiEncoded = Uri.EscapeDataString(_api + _resource);
        string strSignatureBase = "GET&" + apiEncoded + "&api_key=" + oProduct.api_key + "&product_id=" + oProduct.product_id + "&product_name=" + oProduct.product_name + "&price=" + oProduct.price + "&nonce=" + oProduct.nonce + "&timestamp=" + oProduct.timestamp;

        // Create Signature for OAuth 1.0
        oProduct.signature = GenerateSignature(strSignatureBase, _apiSecretKey);

        var client = new RestClient(_api + _resource + "?assertion_id=" + oProduct.assertion_id + "&api_key=" + oProduct.api_key + "&product_id=" + oProduct.product_id + "&product_name=" + oProduct.product_name + "&price=" + oProduct.price + "&timestamp=" + oProduct.timestamp + "&nonce=" + oProduct.nonce + "&signature=" + HttpUtility.UrlEncode(oProduct.signature));
        var request = new RestRequest(Method.GET);
        IRestResponse response = client.Execute(request);

        return "Return whatever you want.";
    }

    public string GenerateTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0));
        string timeStamp = ts.TotalSeconds.ToString();
        timeStamp = timeStamp.Substring(0, timeStamp.IndexOf("."));
        return timeStamp;
    }

    public string GenerateNonce()
    {
        var _random = new Random();
        var sb = new StringBuilder();
        for (int i = 0; i < 8; i++)
        {
            int g = _random.Next(3);
            switch (g)
            {
                case 0:
                    // lowercase alpha
                    sb.Append((char)(_random.Next(26) + 97), 1);
                    break;
                default:
                    // numeric digits
                    sb.Append((char)(_random.Next(10) + 48), 1);
                    break;
            }
        }
        return sb.ToString();
    }

    public string GenerateSignature(string strSignatureBase, string strSecretKey)
    {
        byte[] signatureBaseBytes = Encoding.UTF8.GetBytes(strSignatureBase);
        byte[] secretKeyDecodedBytes = Convert.FromBase64String(strSecretKey); // Decode Secret Key.

        var encoder = new UTF8Encoding();
        var hasher = new HMACSHA1(secretKeyDecodedBytes);

        byte[] hashedDataBytes = hasher.ComputeHash(signatureBaseBytes);

        return Convert.ToBase64String(hashedDataBytes);
    }
}