.net 使用C#强制对Instagram的签名请求

kq0g1dla  于 2023-06-25  发布在  .NET
关注(0)|答案(1)|浏览(128)

我正在尝试与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>");
                        }

                    }
                }

            });
        }

这段代码工作正常,我只是想发送它作为一个签名的请求。

ewm0tg9j

ewm0tg9j1#

Instagram API的“强制签名请求”选项确保只有具有客户端机密的应用程序才能创建对API的请求,即使访问令牌已泄露。您为每个请求生成的签名在理论上是一个不可伪造的令牌,只有您的应用程序和Instagram API可以创建和验证。
为Instagram API创建签名的方法是使用"keyed-hash message authentication code"(HMAC)算法HMAC-SHA 256。在.NET中,您可以使用HMACSHA256 class创建HMAC-SHA 256签名。该函数需要一个要进行身份验证的消息和一个用于此身份验证的密钥。
使用您链接到的页面上的示例,以下是我在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之间保密。

相关问题