PowerShell: Getting an access token from Instagram (oAuth 2.0)

So I’ve recently been struggling with the first step of oAuth 1.0a, which is getting a “request token.” Twitter still uses oAuth 1.0a, and although they have fairly decent documentation on the authentication flow, I’m still having a rough time with it. I had read that supposedly oAuth 2.0 would be easier to work with than oAuth 1.0a, but that didn’t really matter to me since Twitter isn’t using oAuth 2.0 yet.

When push came to shove, and oAuth 1.0a was still giving me headaches, I figured I would just try out oAuth 2.0, to see how easy it was to get an access token. As it turns out, it’s REALLY FREAKIN’ easy, and you don’t have to worry about giving out your application’s consumer secret key (aka. consumer key, client secret, etc.), which is sensitive information. Rather, all you need to do is pass in your callback URL (the one that you configure on your application registration), and the consumer ID (aka. client ID) that the service provides you with.

For a proof of concept, I decided to use Instagram, since it’s … well, popular I guess? I haven’t (as of this writing) used it myself, but I have an account and figured that there would be more than enough data to work with, given its user base. Anyway, diving into the authentication documentation for Instagram, I quickly found an easy, two-step process. For PowerShell, since it’s not a web application, and therefore has no “server side” to it, you can skip down to the “Client-Side (Implicit) Authentication” heading.

The high-level steps are simply:

  1. Call the authorization URL: https://instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
  2. Parse the access token from the callback URL

If we break it down a little bit more, it might look like this:

  1. Direct the user to the authorization URL in a web browser
  2. Have the user log in (if they are not already logged in with a browser cookie)
  3. Click the authorize button for your application when prompted
  4. User/browser is redirected to callback URL + access_token request parameter
  5. Parse access token from browser URL

With all of this in mind, I wrote up a little PowerShell script (function), which I hope is abstract enough to use with other oAuth 2.0 service providers. Let’s take a look:

[cc lines = “-1″ lang=”powershell”]<# .Synopsis Retrieves an oAuth 2.0 access token from the specified base authorization URL, client application ID, and callback URL. .Parameter AuthUrl The base authorization URL defined by the service provider. .Parameter ClientId The client ID (aka. app ID, consumer ID, etc.). .Parameter RedirectUri The callback URL configured on your application's registration with the service provider. .Parameter SleepInterval The number of seconds to sleep while waiting for the user to authorize the application. .Parameter Scope A string array of "scopes" (permissions) that your application will be requesting from the user's account. #>
function Get-oAuth2AccessToken {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)] [string] $AuthUrl
, [Parameter(Mandatory = $true)] [string] $ClientId
, [Parameter(Mandatory = $true)] [string] $RedirectUri
, [int] $SleepInterval = 2
, [Parameter(Mandatory = $true)] [String[]] $Scope
)

# Build the scope of permissions
if (!$Scope) {
$ScopeString = ‘basic’;
}
foreach ($item in $Scope) {
$ScopeString += $item + ‘+’;
}
$ScopeString = $ScopeString.TrimEnd(‘+’);

# Build the request URL from a template
$RequestUrl = ‘{0}?client_id={1}&redirect_uri={2}&response_type=token&scope={3}’ `
-f $AuthUrl, $ClientId, $RedirectUri, $ScopeString;
Write-Debug -Message (‘Request URL is: {0}’ -f $RequestUrl);

# Create the Internet Explorer object and navigate to the constructed authorization URL
$IE = New-Object -ComObject InternetExplorer.Application;
$IE.Navigate($RequestUrl);
$IE.Visible = $true;

# Sleep the script for $X seconds until callback URL has been reached
# NOTE: If user cancels authorization, this condition will not be satisifed
while ($IE.LocationUrl -notmatch ‘access_token=’) {
Write-Debug -Message (‘Sleeping {0} seconds for access URL’ -f $SleepInterval);
Start-Sleep -Seconds $SleepInterval;
}

# Parse the access token from the callback URL and exit Internet Explorer
Write-Debug -Message (‘Callback URL is: {0}’ -f $IE.LocationUrl);
[Void]($IE.LocationUrl -match ‘=([\w\.]+)’);
$AccessToken = $Matches[1];
$IE.Quit();

# Write the access token to the pipeline inside of a HashTable (in case we want to return other properties later)
Write-Debug -Message (‘Access token is: {0}’ -f $AccessToken);
Write-Output -InputObject @{ AccessToken = $AccessToken; };
}

$DebugPreference = ‘continue’; #Enable debug messages to be sent to console

$AuthUrl = ‘https://instagram.com/oauth/authorize/’; # The base authorization URL from the service provider
$ClientId = ‘83956d6cbdd14380be86673e344bd352’; # Your registered application’s client ID
$RedirectUri = ‘http://trevorsullivan.net’; # The callback URL configured on your application
$Scope = @(‘basic’,’likes’,’comments’,’relationships’); # A string array of “scopes” (permissions) your application is requesting

Get-oAuth2AccessToken `
-AuthUrl $AuthUrl `
-ClientId $ClientId `
-RedirectUri $RedirectUri `
-Scope $Scope;[/cc]