Instagram Setting up an authentication page

Setting up an authentication page

If you're looking to setup an authentication page where your users (or yourself) can log in with their Instagram account, the first step is initialize a new instance of the InstagramOAuthClient class.

This class is mostly used internally in Skybrud.Social for handling the raw communication with the Instagram API, but it also contains the logic needed for authenticating users. You can initialize a new instance of the class like this:

// Initialize and configure the OAuth client
InstagramOAuthClient client = new InstagramOAuthClient {
    ClientId = "Insert your client ID here",
    ClientSecret = "Insert your client secret here",
    RedirectUri = "https://social.abjerner/instagram/oauth"
};

You can find the client ID and secret of your app via Instagram's Manage Clients, as well as specify the redirect URI that matches your authentication page - eg. https://social.abjerner/instagram/oauth for my local test site.

Generating the authorization URL

The next step is to redirect the user to Instagram's authorization page - this is where the user confirms (or denies) that your app can gain access to his/her account with the requested permissions (called scope).

The client instance will help you generate the URL the this authorization page using the GetAuthorizationUrl method:

// Generate the authorization URL (with default scope)
string authorizationUrl = client.GetAuthorizationUrl(state);

For this method, you must specify a state parameter, which is a random generated value that you will later need to approve the user once he/she is redirected back to your site. You can store the state in a session or similar.

By default, you will only be given basic permissions to the user's account. If you need more permissions, you can also explicitly specify these via an overload of the GetAuthorizationUrl method:

// Generate the authorization URL
string authorizationUrl = client.GetAuthorizationUrl(state, InstagramScopes.Basic + InstagramScopes.PublicContent);

In this example, you will request both the basic scope as well as the public_content scope. Notice that the latter requires prior approval by Instagram.

Getting the authorization code

Once the user confirms (or denies) your app the requested permissions, he/she is redirected back to your page. If confirmed, a code parameter will be included in the query string. This parameter is an authorization code that you will need to obtain the actual access token of the user.

If the user cancels, he/she will still be redirected back to your page, but with the error, error_reason and error_description parameters in the query string instead.

Obtaining an access token

The access token can be obtained using the GetAccessTokenFromAuthCode method, where the response body will reveal the access token.

For the example below, the authorizationCode parameter is the authorization code received when the user has successfully logged in through the Instagram login dialog, and been redirected back to your site. At this point, the code parameter in the query string will contain the authorization code.

The code for exchanging the authorization code for the access token will look like:

// Exchange the authorization code for an access token
InstagramTokenResponse response = client.GetAccessTokenFromAuthCode(authCode);

// Get the access token from the response body
string accessToken = response.Body.AccessToken;

Initializing an instance of InstagramService

Once you have obtained an access token, you can initialize a new instance of the InstagramService class as shown in the example below:

// Initialize a new service instance from an access token
InstagramService service = InstagramService.CreateFromAccessToken("Insert your access token here");

The InstagramService class serves as your starting point to making calls to the Instagram API.

Complete example

In the example below, I've tried to demonstrate how a login page can be implemented (involving the steps explained above).

Notice that the example generates a state that is saved to the user's session. When redirecting the user to Instagram's authorization page, we supply the state, and once the user confirms (or cancels) the authorization, the same state is specified in the URL the user is redirected back to (at your site). We can then check whether the state is saved in the user session to make sure it's still the same user making the request.

@using Skybrud.Social.Instagram.OAuth
@using Skybrud.Social.Instagram.Responses.Authentication
@using Skybrud.Social.Instagram.Scopes

@{

    // Initialize a new OAuth client with the information from your app
    InstagramOAuthClient client = new InstagramOAuthClient {
        ClientId = "Your client ID",
        ClientSecret = "Your client secret",
        RedirectUri = "https://social.abjerner/instagram/oauth/"
    };

    if (Request.QueryString["do"] == "login") {

        // Generate a random scope
        string state = Guid.NewGuid().ToString();

        // Generate the session key for the state
        string stateKey = "InstagramOAuthState_" + state;

        // Store the state in the session of the user
        Session[stateKey] = Request.RawUrl;

        // Generate the authorization URL
        string authorizationUrl = client.GetAuthorizationUrl(state, InstagramScopes.PublicContent);

        // Redirect the user
        Response.Redirect(authorizationUrl);

    } else if (Request.QueryString["code"] != null) {

        // Get the state from the query string
        string state = Request.QueryString["state"];

        // Get the code from the query string
        string code = Request.QueryString["code"];

        // Generate the session key for the state
        string stateKey = "InstagramOAuthState_" + state;

        if (Session[stateKey] == null) {
            <p>Has your session expired?</p>
            <p>
                <a class="btn btn-default" href="/instagram/oauth?do=login">Re-try login</a>
            </p>
            return;
        }

        InstagramTokenResponse response = client.GetAccessTokenFromAuthCode(code);

        <div class="alert alert-info">
            <p>Hi <strong>@(response.Body.User.FullName ?? response.Body.User.Username)</strong></p>
            <p>Id: @response.Body.User.Id</p>
            <p>Username: @response.Body.User.Username</p>
            @if (!String.IsNullOrWhiteSpace(response.Body.User.ProfilePicture)) {
                <img src="@response.Body.User.ProfilePicture" />
            }
        </div>

        <br />

        <div>Access Token:</div>
        <pre>@response.Body.AccessToken</pre>

        return;

    }

    <p>
        <a class="btn btn-default" href="/instagram/oauth?do=login">Login with Instagram</a>
    </p>

}