CINXE.COM
Secure Requests • Instagram Developer Documentation
<!DOCTYPE html> <!--[if lt IE 7]> <html lang="en" class="no-js lt-ie9 lt-ie8 lt-ie7 not-logged-in "> <![endif]--> <!--[if IE 7]> <html lang="en" class="no-js lt-ie9 lt-ie8 not-logged-in "> <![endif]--> <!--[if IE 8]> <html lang="en" class="no-js lt-ie9 not-logged-in "> <![endif]--> <!--[if gt IE 8]><!--> <html lang="en" class="no-js not-logged-in "> <!--<![endif]--> <head><script type="text/javascript" src="/_static/js/bundle-playback.js?v=HxkREWBo" charset="utf-8"></script> <script type="text/javascript" src="/_static/js/wombat.js?v=txqj7nKC" charset="utf-8"></script> <script>window.RufflePlayer=window.RufflePlayer||{};window.RufflePlayer.config={"autoplay":"on","unmuteOverlay":"hidden"};</script> <script type="text/javascript" src="/_static/js/ruffle/ruffle.js"></script> <script type="text/javascript"> __wm.init("https://web.archive.org/web"); __wm.wombat("https://instagram.com/developer/secure-api-requests/","20151120103910","https://web.archive.org/","web","/_static/", "1448015950"); </script> <link rel="stylesheet" type="text/css" href="/_static/css/banner-styles.css?v=S1zqJCYt" /> <link rel="stylesheet" type="text/css" href="/_static/css/iconochive.css?v=3PDvdIFv" /> <!-- End Wayback Rewrite JS Include --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Secure Requests • Instagram Developer Documentation</title> <script type="text/javascript"> WebFontConfig = { custom: { families: ['proxima-nova:n3,n4,n6,n7'], } }; </script> <script src="//web.archive.org/web/20151120103910js_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/scripts/webfont.js" type="text/javascript" async></script> <style type="text/css"> /* @license * MyFonts Webfont Build ID 2164953, 2012-03-23T23:06:30-0400 * * The fonts listed in this notice are subject to the End User License * Agreement(s) entered into by the website owner. All other parties are * explicitly restricted from using the Licensed Webfonts(s). * * You may obtain a valid license at the URLs below. * * * Webfont: Proxima Nova Light by Mark Simonson * URL: http://www.myfonts.com/fonts/marksimonson/proxima-nova/light/ * Licensed pageviews: unlimited * * Webfont: Proxima Nova Regular by Mark Simonson * URL: http://www.myfonts.com/fonts/marksimonson/proxima-nova/regular/ * Licensed pageviews: unlimited * * Webfont: Proxima Nova Semibold by Mark Simonson * URL: http://www.myfonts.com/fonts/marksimonson/proxima-nova/semibold/ * Licensed pageviews: unlimited * * Webfont: Proxima Nova Bold Italic by Mark Simonson * URL: http://www.myfonts.com/fonts/marksimonson/proxima-nova/bold-it/ * Licensed pageviews: unlimited * * Webfont: Proxima Nova Bold by Mark Simonson * URL: http://www.myfonts.com/fonts/marksimonson/proxima-nova/bold/ * Licensed pageviews: unlimited * * Webfont: Proxima Nova Italic by Mark Simonson * URL: http://www.myfonts.com/fonts/marksimonson/proxima-nova/regular-it/ * Licensed pageviews: unlimited * * * License: http://www.myfonts.com/viewlicense?type=web&buildid=2164953 * Webfonts copyright: Copyright (c) Mark Simonson, 2005. All rights reserved. * * (c) 2012 Bitstream Inc */ @font-face { font-family: 'proxima-nova'; src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-bold-webfont.eot'); src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-bold-webfont.eot#iefix') format("embedded-opentype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-bold-webfont.woff') format("woff"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-bold-webfont.ttf') format("truetype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-bold-webfont.svg#ProximaNovaBold') format("svg"); font-weight: bold; font-style: normal; } @font-face { font-family: 'proxima-nova'; src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-boldit-webfont.eot'); src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-boldit-webfont.eot#iefix') format("embedded-opentype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-boldit-webfont.woff') format("woff"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-boldit-webfont.ttf') format("truetype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-boldit-webfont.svg#ProximaNovaBoldItalic') format("svg"); font-weight: bold; font-style: italic; } @font-face { font-family: 'proxima-nova'; src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-reg-webfont.eot'); src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-reg-webfont.eot#iefix') format("embedded-opentype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-reg-webfont.woff') format("woff"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-reg-webfont.ttf') format("truetype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-reg-webfont.svg#ProximaNovaRegular') format("svg"); font-weight: normal; font-style: normal; } @font-face { font-family: 'proxima-nova'; src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-regit-webfont.eot'); src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-regit-webfont.eot#iefix') format("embedded-opentype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-regit-webfont.woff') format("woff"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-regit-webfont.ttf') format("truetype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-regit-webfont.svg#ProximaNovaRegularItalic') format("svg"); font-weight: normal; font-style: italic; } @font-face { font-family: 'proxima-nova'; src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-sbold-webfont.eot'); src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-sbold-webfont.eot#iefix') format("embedded-opentype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-sbold-webfont.woff') format("woff"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-sbold-webfont.ttf') format("truetype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-sbold-webfont.svg#ProximaNovaSemibold') format("svg"); font-weight: 600; font-style: normal; } </style> <style type="text/css"> @font-face { font-family: 'proxima-nova'; src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-light-webfont.eot'); src: url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-light-webfont.eot#iefix') format("embedded-opentype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-light-webfont.woff') format("woff"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-light-webfont.ttf') format("truetype"), url('//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/webfonts/proximanova-light-webfont.svg#ProximaNovaLight') format("svg"); font-weight: 300; font-style: normal; } </style> <meta name="robots" content="noimageindex"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta id="viewport" name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, minimum-scale=1, maximum-scale=1"> <script type="text/javascript"> (function() { var docElement = document.documentElement; var classRE = new RegExp('(^|\\s)no-js(\\s|$)'); var className = docElement.className; docElement.className = className.replace(classRE, '$1js$2'); })(); </script> <link rel="Shortcut Icon" type="image/x-icon" href="//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/images/ico/favicon.ico"><link rel="mask-icon" href="//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/images/ico/favicon.svg" color="#125688"> <link rel="apple-touch-icon-precomposed" href="//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/images/ico/apple-touch-icon-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="72x72" href="//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/images/ico/apple-touch-icon-72x72-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/images/ico/apple-touch-icon-114x114-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="//web.archive.org/web/20151120103910im_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/images/ico/apple-touch-icon-144x144-precomposed.png"> <link href="//web.archive.org/web/20151120103910cs_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/styles/developer/developer-main.css" type="text/css" rel="stylesheet"></link> <script src="//web.archive.org/web/20151120103910js_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/scripts/jquery.js" type="text/javascript"></script> <script src="//web.archive.org/web/20151120103910js_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/scripts/bluebar.js" type="text/javascript"></script> <script src="//web.archive.org/web/20151120103910js_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/scripts/navigation.js" type="text/javascript"></script> <script> $(document).ready(function() { $('#top_bar_right .top-bar-actions').prepend("<li class='manage-clients link-settings'><a class='' href='/developer/clients/manage/'>Manage Clients<i></i></a></li>"); $('#top_bar_right .top-bar-actions').prepend("<li class='testing-clients link-settings'><a class='' href='/developer/clients/sandbox_invites/'>Sandbox Invites<i></i></a></li>"); }); </script> </head> <body class="sidebar-page"> <div class="root"> <div class="page"> <header class="top-bar"> <div class="wrapper"> <hgroup> <div class="logo"><a href="/web/20151120103910/https://instagram.com/">Instagram</a></div> </hgroup> <div class="top-bar-right account-state" id="top_bar_right"> <ul class="top-bar-actions" id="top_bar_actions"> <li id="link_profile" class="link-signin"> <a href="/web/20151120103910/https://instagram.com/accounts/login/?next=/developer/secure-api-requests/"> <i></i> <strong>Log in</strong> </a> </li> </ul> </div> </div> </header> <!-- .top-bar --> <div class="sidebar"> <div class="wrapper"> <nav class="sidebar-nav"> <div class="sidebar-content"> <form class="quick-search" action="/web/20151120103910/https://instagram.com/developer/search/" method="GET"> <a href="#" class="disclosure-down"></a> <input name="q" type="text" placeholder="Search Documentation"/> <input type="submit"/> </form> <ul> <li> <a href="/web/20151120103910/https://instagram.com/developer/"> Overview <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/authentication/"> Authentication <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/authorization/"> Login Permissions <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/review/"> Permissions Review <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/sandbox/"> Sandbox Mode <i class="disclosure"></i> </a> </li> <li class="active"> <a href="/web/20151120103910/https://instagram.com/developer/secure-api-requests/"> Secure Requests <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/endpoints/"> Endpoints <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/limits/"> Rate Limits <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/subscriptions/"> Subscriptions <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/embedding/"> Embedding <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/mobile-sharing/"> Mobile Sharing <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/libraries/"> Libraries <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/support/"> Support <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/developer/changelog/"> Changelog <i class="disclosure"></i> </a> </li> <li> <a href="/web/20151120103910/https://instagram.com/about/legal/terms/api/"> Platform Policy <i class="disclosure"></i> </a> </li> </ul> </div> </nav> </div> </div> <div class="main"> <div class="wrapper"> <section class="nav-page-content" role="main"> <div id="alerts" class="alerts"> <p class="alert-blue"><b>Instagram Platform and documentation update.</b> Apps created on or after Nov 17, 2015 will start in Sandbox Mode and function on newly updated API rate-limits and behaviors. Prior to going Live, and being able to be used by people other than the developers of the app, these apps will have to go through a new review process. Please read the <a href="/web/20151120103910/https://instagram.com/developer/">API documentation</a> or the <a href="/web/20151120103910/https://instagram.com/developer/changelog/">Change Log</a> for more details.<br><br> Any app created before Nov 17, 2015 will continue to function <b>until June 2016</b>. After June 2016, the app will automatically be moved to Sandbox Mode if it wasn't approved through the review process. The previous version of our documentation is stil available <a href="/web/20151120103910/https://instagram.com/developer/deprecated/">here</a>.</p> </div> <h1 id="secure-requests">Secure Requests</h1> <p>Most API calls require an access token, but malicious developers can impersonate OAuth Clients or steal access tokens. They will then use these to send spam on the behalf of your app. Instagram has automated systems to detect spam, and will automatically disable the OAuth Clients responsible for these calls. You can mitigate the risk of your app being disabled by restricting some vectors of abuses. This document covers some of the ways you can protect your app.</p> <h2 id="disable-client-side-implicit-authentication">Disable Client-Side (Implicit) Authentication</h2> <p>The <a href="/web/20151120103910/https://instagram.com/developer/authentication/">Implicit OAuth Grant flow</a> was created for java-script or mobile clients. Many developers use this flow because of its convenience. Unfortunately, malicious developers can also use this flow to trick people into authorizing your OAuth Client. They can collect access tokens and then make API calls on behalf of your app. When this occurs, your OAuth Client could be banned from the platform by our spam detection systems.</p> <p>If your app is powered by a server infrastructure, you can disable the Client-Side (Implicit) OAuth flow by checking the <strong>Disable implicit OAuth</strong> setting in your OAuth Client configuration. If checked, Instagram will reject Client-Side (Implicit) authorization requests and only grant Server-Side (Explicit) authorization requests. This setting helps protect your app because the Server-Side (Explicit) OAuth flow requires the use of your Client Secret, which should be unknown to malicious developers.</p> <blockquote> <h2 id="important">Important</h2> <p>Your Client Secret should be kept secure at all times. Do not share this Secret with anyone, do not include it in java-script code or a mobile client. Mobile apps that do not have a server-side component should have the <strong>Disable implicit OAuth</strong> setting unchecked. You have the ability to reset your Client Secret to a new value at any time, if you suspect that it was leaked.</p> </blockquote> <h2 id="enforce-signed-requests">Enforce Signed Requests</h2> <p>Access tokens are portable: they can be generated on one machine and re-used elsewhere. Access tokens can also be stolen by malicious software on a person's computer or a man in the middle attack. A stolen access token can then be used to generate spam. When targeted by such abuses, your app could be blocked by our automated systems.</p> <p>You can secure your API calls and mitigate impersonation attempts by making server-side calls and passing a per-request signature using your Client Secret. Edit your OAuth Client configuration and mark the <strong>Enforce signed requests</strong> checkbox. When enabled, Instagram will check for the <em>sig</em> parameter of each request and verify that the value matches a hash computed using your Client Secret. The expected value is a HMAC using the SHA256 hash algorithm with all your request parameters and your Client Secret.</p> <blockquote> <h2 id="important_1">Important</h2> <p>Your Client Secret should be kept secure at all times. Do not share this Secret with anyone, do not include it in java-script code or a mobile client. Mobile apps that do not have a server-side component should not use the <strong>Enforce signed requests</strong> setting. You have the ability to reset your Client Secret to a new value at any time, if you suspect that it was leaked.</p> </blockquote> <h3 id="signature-format">Signature format</h3> <div class="codehilite"><pre><code><span class="n">Token</span> <span class="n">to</span> <span class="nb">sign</span><span class="p">:</span> <span class="n">endpoint</span><span class="o">|</span><span class="n">key1</span><span class="p">=</span><span class="n">value1</span><span class="o">|</span><span class="n">key2</span><span class="p">=</span><span class="n">value2</span><span class="o">|</span><span class="p">...</span> <span class="n">Parameter</span> <span class="n">name</span><span class="p">:</span> <span class="n">sig</span> <span class="n">Parameter</span> <span class="n">value</span><span class="p">:</span> <span class="n">signed</span> <span class="n">token</span> <span class="n">with</span> <span class="n">your</span> <span class="n">Client</span> <span class="n">Secret</span> <span class="n">using</span> <span class="n">the</span> <span class="n">SHA256</span> <span class="n">hash</span> <span class="n">algorithm</span> </code></pre></div> <ul> <li>Token: API endpoint appended with a concatenation of all key/value pairs of your request parameters, <strong>sorted by key</strong> in ascending order. Each key/value pair is separated by the pipe character.</li> </ul> <h3 id="examples">Examples</h3> <p>Endpoint: /users/self Parameters: access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d App Secret: 6dc1787668c64c939929c17683d7cb74</p> <p>With this example, the signature key/value should be:</p> <div class="codehilite"><pre><code><span class="n">sig</span><span class="p">=</span><span class="n">cbf5a1f41db44412506cb6563a3218b50f45a710c7a8a65a3e9b18315bb338bf</span> </code></pre></div> <p>Endpoint: /media/657988443280050001_25025320 Parameters: access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&count=10 App Secret: 6dc1787668c64c939929c17683d7cb74</p> <p>Here the signature key/value would then be:</p> <div class="codehilite"><pre><code><span class="n">sig</span><span class="p">=</span>260634<span class="n">b241a6cfef5e4644c205fb30246ff637591142781b86e2075faf1b163a</span> </code></pre></div> <p>The signature describes the hex representation of a RFC 2104-compliant HMAC with the SHA256 hash algorithm, using the API endpoint, your request parameters and your Client Secret. Most programming languages provide the tools to create such a signature. Here are some examples to get you started.</p> <h3 id="python">Python</h3> <div class="codehilite"><pre><code><span class="c"># -*- coding: UTF-8 -*-</span> <span class="kn">import</span> <span class="nn">hmac</span> <span class="kn">from</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="n">sha256</span> <span class="k">def</span> <span class="nf">generate_sig</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">secret</span><span class="p">):</span> <span class="n">sig</span> <span class="o">=</span> <span class="n">endpoint</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">params</span><span class="o">.</span><span class="n">keys</span><span class="p">()):</span> <span class="n">sig</span> <span class="o">+=</span> <span class="s">'|</span><span class="si">%s</span><span class="s">=</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">params</span><span class="p">[</span><span class="n">key</span><span class="p">])</span> <span class="k">return</span> <span class="n">hmac</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">secret</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sha256</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="n">endpoint</span> <span class="o">=</span> <span class="s">'/media/657988443280050001_25025320'</span> <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> <span class="s">'access_token'</span><span class="p">:</span> <span class="s">'fb2e77d.47a0479900504cb3ab4a1f626d174d2d'</span><span class="p">,</span> <span class="s">'count'</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="p">}</span> <span class="n">secret</span> <span class="o">=</span> <span class="s">'6dc1787668c64c939929c17683d7cb74'</span> <span class="n">sig</span> <span class="o">=</span> <span class="n">generate_sig</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">secret</span><span class="p">)</span> <span class="k">print</span> <span class="n">sig</span> </code></pre></div> <h3 id="ruby">Ruby</h3> <div class="codehilite"><pre><code><span class="nb">require</span> <span class="s1">'openssl'</span> <span class="nb">require</span> <span class="s1">'base64'</span> <span class="k">def</span> <span class="nf">generate_sig</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">secret</span><span class="p">)</span> <span class="n">sig</span> <span class="o">=</span> <span class="n">endpoint</span> <span class="n">params</span><span class="o">.</span><span class="n">sort</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="o">|</span> <span class="n">sig</span> <span class="o">+=</span> <span class="s1">'|%s=%s'</span> <span class="o">%</span> <span class="o">[</span><span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="o">]</span> <span class="k">end</span> <span class="n">digest</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">Digest</span><span class="o">::</span><span class="no">Digest</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">'sha256'</span><span class="p">)</span> <span class="k">return</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">HMAC</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(</span><span class="n">digest</span><span class="p">,</span> <span class="n">secret</span><span class="p">,</span> <span class="n">sig</span><span class="p">)</span> <span class="k">end</span> <span class="n">endpoint</span> <span class="o">=</span> <span class="s1">'/media/657988443280050001_25025320'</span> <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'access_token'</span> <span class="o">=></span> <span class="s1">'fb2e77d.47a0479900504cb3ab4a1f626d174d2d'</span><span class="p">,</span> <span class="s1">'count'</span> <span class="o">=></span> <span class="mi">10</span><span class="p">,</span> <span class="p">}</span> <span class="n">secret</span> <span class="o">=</span> <span class="s1">'6dc1787668c64c939929c17683d7cb74'</span> <span class="n">sig</span> <span class="o">=</span> <span class="n">generate_sig</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">secret</span><span class="p">)</span> <span class="nb">print</span> <span class="n">sig</span> </code></pre></div> <h3 id="php">PHP</h3> <div class="codehilite"><pre><code><span class="cp"><?php</span> <span class="k">function</span> <span class="nf">generate_sig</span><span class="p">(</span><span class="nv">$endpoint</span><span class="p">,</span> <span class="nv">$params</span><span class="p">,</span> <span class="nv">$secret</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$sig</span> <span class="o">=</span> <span class="nv">$endpoint</span><span class="p">;</span> <span class="nb">ksort</span><span class="p">(</span><span class="nv">$params</span><span class="p">);</span> <span class="k">foreach</span> <span class="p">(</span><span class="nv">$params</span> <span class="k">as</span> <span class="nv">$key</span> <span class="o">=></span> <span class="nv">$val</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$sig</span> <span class="o">.=</span> <span class="s2">"|</span><span class="si">$key</span><span class="s2">=</span><span class="si">$val</span><span class="s2">"</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">hash_hmac</span><span class="p">(</span><span class="s1">'sha256'</span><span class="p">,</span> <span class="nv">$sig</span><span class="p">,</span> <span class="nv">$secret</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span> <span class="p">}</span> <span class="nv">$endpoint</span> <span class="o">=</span> <span class="s1">'/media/657988443280050001_25025320'</span><span class="p">;</span> <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span> <span class="s1">'access_token'</span> <span class="o">=></span> <span class="s1">'fb2e77d.47a0479900504cb3ab4a1f626d174d2d'</span><span class="p">,</span> <span class="s1">'count'</span> <span class="o">=></span> <span class="mi">10</span><span class="p">,</span> <span class="p">);</span> <span class="nv">$secret</span> <span class="o">=</span> <span class="s1">'6dc1787668c64c939929c17683d7cb74'</span><span class="p">;</span> <span class="nv">$sig</span> <span class="o">=</span> <span class="nx">generate_sig</span><span class="p">(</span><span class="nv">$endpoint</span><span class="p">,</span> <span class="nv">$params</span><span class="p">,</span> <span class="nv">$secret</span><span class="p">);</span> <span class="k">echo</span> <span class="nv">$sig</span><span class="p">;</span> </code></pre></div> <h3 id="testing-signed-requests">Testing Signed Requests</h3> <p>Using an invalid signature will cause your API calls to fail if the <strong>Enforce signed requests</strong> setting is set. Because of this, you may want to test this parameter before you enable the setting for production code. Fortunately you can use cURL to test your header format and signature easily:</p> <div class="codehilite"><pre><code>curl <span class="se">\</span> -X POST <span class="se">\</span> -F <span class="s1">'access_token=<your_access_token>'</span> <span class="se">\</span> -F <span class="s1">'sig=<your_signature>'</span> <span class="se">\</span> https://api.instagram.com/v1/media/657988443280050001_25025320/likes </code></pre></div> <p>Common responses:</p> <table> <thead> <tr> <th>REASON</th> <th>RESPONSE</th> </tr> </thead> <tbody> <tr> <td>Success</td> <td>{"meta":{"code":200},"data":null}</td> </tr> <tr> <td>Signature is required</td> <td>{"code": 403, "error_type": "OAuthForbiddenException", "error_message": "Missing required parameter 'sig'"}</td> </tr> <tr> <td>Failed to validate signature</td> <td>{"code": 403, "error_type": "OAuthForbiddenException", "error_message": "Signature does not match"}</td> </tr> </tbody> </table> </section> </div> <!-- .main --> </div> <!-- .main --> </div> <!-- .page --> <footer class="page-footer" role="contentinfo"> <div class="wrapper"> <nav> <ul> <li><a href="/web/20151120103910/https://instagram.com/about/us/">About us</a></li> <li><a href="https://web.archive.org/web/20151120103910/http://help.instagram.com/">Support</a></li> <li><a href="https://web.archive.org/web/20151120103910/http://blog.instagram.com/">Blog</a></li> <li><a href="https://web.archive.org/web/20151120103910/http://instagram.com/press/">Press</a></li> <li><a href="/web/20151120103910/https://instagram.com/developer/">API</a></li> <li><a href="/web/20151120103910/https://instagram.com/about/jobs/">Jobs</a></li> <li><a href="/web/20151120103910/https://instagram.com/legal/privacy/">Privacy</a></li> <li><a href="/web/20151120103910/https://instagram.com/legal/terms/">Terms</a></li> </ul> </nav> <p class="copyright">© 2015 Instagram</p> </div> </footer> <div id="reactModalMountPoint"></div> </div> <!-- .root --> <script src="//web.archive.org/web/20151120103910js_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/scripts/polyfills/es5-shim.min.js"></script> <script src="//web.archive.org/web/20151120103910js_/https://instagramstatic-a.akamaihd.net/bluebar/bd9471f/scripts/polyfills/es5-sham.min.js"></script> <script type="text/javascript">window._sharedData = {"qs":"{\"shift\":10,\"header\":\"fXYSiu8dgexGrYr7X6GmJEVFD2L5XD2C\",\"edges\":100,\"blob\":\"AQBayDcwKXDPh3w-exUhTFRkGl9Bn1aCyatbrZu1FSO-MlAtLJo2OQ8JG6qHgJgvykt-eCNLW6zAvJRAUOosyGTgtx1DCZUMebfU1asyAt7k0KtYGCfa9vk1fSQF_p7I8fLG4nKGk1Dm5sjgF27FpqkzO7H_nlGdSOHoSR3XqgjTOT_JuCSxrja_5n4tvvTk5tpZdpDIZpIsLWjd7M3OO-ylslDU0HxY4k4qXuexLK_yJw\",\"iterations\":7,\"size\":42}","static_root":"\/\/web.archive.org\/web\/20151120103910\/https:\/\/instagramstatic-a.akamaihd.net\/bluebar\/bd9471f","entry_data":{},"hostname":"instagram.com","platform":"web","qe":{"su":{"p":{},"g":""}},"display_properties_server_guess":{"viewport_width":360,"pixel_ratio":1.5},"country_code":"US","language_code":"en","gatekeepers":{"rhp":true},"config":{"dismiss_app_install_banner_until":null,"viewer":null,"csrf_token":"319b5f4e0c31acfb6ab7934088fc5b1b"},"environment_switcher_visible_server_guess":true};</script> <script> !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','//web.archive.org/web/20151120103910/https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '1425767024389221'); fbq('track', 'PageView'); </script> <noscript> </noscript> </body> </html><!-- FILE ARCHIVED ON 10:39:10 Nov 20, 2015 AND RETRIEVED FROM THE INTERNET ARCHIVE ON 00:45:27 Nov 29, 2024. JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE. ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C. SECTION 108(a)(3)). --> <!-- playback timings (ms): captures_list: 0.61 exclusion.robots: 0.033 exclusion.robots.policy: 0.021 esindex: 0.011 cdx.remote: 7.706 LoadShardBlock: 248.407 (3) PetaboxLoader3.datanode: 210.569 (4) PetaboxLoader3.resolve: 126.724 (3) load_resource: 101.627 -->