使用c#强制签名请求到Instagram

本文关键字:请求 Instagram 使用 | 更新日期: 2023-09-27 18:08:04

我正在尝试与Instagram API进行通信,并希望按照下面给出的链接使用签名请求与API进行安全通信

https://instagram.com/developer/secure-api-requests/

在默认页面,我简单地获取客户端密钥,客户端密码和重定向URL等详细信息,并通过Instagram进行认证。

验证后,在重定向URL,下面是我的代码:

//To Get Access Token
var json = "";
 NameValueCollection parameters = new NameValueCollection();
                parameters.Add("client_id", ConfigurationManager.AppSettings["instagram.clientid"].ToString());
                parameters.Add("client_secret", ConfigurationManager.AppSettings["instagram.clientsecret"].ToString());
                parameters.Add("grant_type", "authorization_code");
                parameters.Add("redirect_uri", ConfigurationManager.AppSettings["instagram.redirecturi"].ToString());
                parameters.Add("code", code);
                WebClient client = new WebClient();
                var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "POST", parameters);
                var response = System.Text.Encoding.Default.GetString(result);
                // deserializing nested JSON string to object
                var jsResult = (JObject)JsonConvert.DeserializeObject(response);
                string accessToken = (string)jsResult["access_token"];
                int id = (int)jsResult["user"]["id"];
Page.ClientScript.RegisterStartupScript(this.GetType(), "GetToken", "<script>var instagramaccessid='"" + @"" + id + "" + "'"; var instagramaccesstoken='"" + @"" + accessToken + "" + "'";</script>");

在获得访问令牌之后,让我们说我从Instagram获得了热门照片。下面是保存热门照片的div

 <div style="clear:both;"></div>
        <div>
            <h1>
                Popular Pictures</h1>
            <div id="PopularPhotosDiv">
                <ul id="photosUL1">
                </ul>
            </div>
        </div>

然后使用下面的函数来填充热门照片

的div
 <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {           
            GetPopularPhotos();
           
        });
function GetPopularPhotos() {
            $("#photosUL1").html("");
            $.ajax({
                type: "GET",
                async: true,
                contentType: "application/json; charset=utf-8",
                //Most popular photos
                url: "https://api.instagram.com/v1/media/popular?access_token=" + instagramaccesstoken,
                dataType: "jsonp",
                cache: false,
                beforeSend: function () {
                    $("#loading").show();
                },
                success: function (data)
                {
                    $("#loading").hide();
                    if (data == "") {
                        $("#PopularPhotosDiv").hide();
                    } else {
                        $("#PopularPhotosDiv").show();
                        for (var i = 0; i < data["data"].length; i++) {
                            $("#photosUL1").append("<li style='float:left;list-style:none;'><a target='_blank' href='" + data.data[i].link + "'><img src='" + data.data[i].images.thumbnail.url + "'></img></a></li>");
                        }
                    }
                }
            });
        }

这段代码工作得很好,我只是想把它作为一个签名请求发送。

使用c#强制签名请求到Instagram

Instagram API的强制签名请求选项确保只有具有客户端秘密的应用程序才能创建对API的请求,即使访问令牌已经泄露。您为每个请求生成的签名理论上是一个不可伪造的令牌,只有您的应用程序和Instagram API可以创建和验证。

为Instagram API创建签名的方法是使用HMAC算法HMAC- sha256。在。net中,可以使用HMACSHA256类创建HMAC-SHA256签名。该函数需要一个将被身份验证的消息和用于此身份验证的秘密密钥。

使用你链接到的页面上的示例,下面是我在c#中想到的生成这些签名的方法:

static string GenerateSignature(string endpoint, Dictionary<string,string> parameters, string secret)
{
    // Build the message to be authenticated
    StringBuilder message = new StringBuilder(endpoint);
    foreach (var param in parameters.OrderBy(p => p.Key))
    {
        message.AppendFormat("|{0}={1}", param.Key, param.Value);
    }
    // Create a HMAC-SHA256 digest of the message using the secret key
    HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
    byte[] digest = hmac.ComputeHash(Encoding.UTF8.GetBytes(message.ToString()));
    // Return the digest as a hexstring to be used as a signature for the request
    return ByteArrayToString(digest);
}
static string ByteArrayToString(byte[] array)
{
    // Convert the bytes in the array to a lower-case hexstring
    return array.Aggregate(new StringBuilder(), (sb, b) => sb.Append(b.ToString("x2"))).ToString();
}
static void Main(string[] args)
{
    string secret = "6dc1787668c64c939929c17683d7cb74";
    string endpoint;
    Dictionary<string, string> parameters;
    string signature;
    // Example 1
    endpoint = "/users/self";
    parameters = new Dictionary<string, string>
    {
        { "access_token", "fb2e77d.47a0479900504cb3ab4a1f626d174d2d" },
    };
    signature = GenerateSignature(endpoint, parameters, secret);
    Console.WriteLine("sig={0}", signature);
    // Example 2
    endpoint = "/media/657988443280050001_25025320";
    parameters = new Dictionary<string, string>
    {
        { "access_token", "fb2e77d.47a0479900504cb3ab4a1f626d174d2d" },
        { "count", "10" },
    };
    signature = GenerateSignature(endpoint, parameters, secret);
    Console.WriteLine("sig={0}", signature);
    Console.ReadKey(true);
}

生成的签名应该与文档示例中给出的签名相匹配。

正如Instagram的文档所警告的那样,永远不要让这个客户端密钥公开可用。换句话说,确保客户端秘密不会在移动设备、网站JavaScript、桌面应用程序等上传播。你和Instagram之间应该永远保密。