Sample Console Application using Client Credentials using JavaScript Sync

Run Sample Download Sample Source

For applications that do not need to Authenticate the user because the app is not going to access user date, the application can use the OAuth Client Credential Flow. This uses the Client ID and Client Secret that the application developer registered on CodeProject. Because a web page is not a secure place to store client credentials, this is not a recommended method.

Note: The demos use a pre-registered Client ID and Client Secret. For your apps, you will need to register your own. Information about registering a Client ID and Client Secret can be found here.

The following code demonstrates an HTML page that get the first page of the latest Articles and displays the title. The API requests and handling the response is performed synchronously. You can see the sample in action by clicking. Clicking on the Get Article button in the sample will request the page of Articles from the server, displaying status along the way.

The sample consists of two files:

The HTML page contains

Index.html listing

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>API example using OAuth2 Client Credentials.</title>
</head>

<body>
    <h2>API example using OAuth2 Client Credentials.</h2>
    <p>
        This sample demonstrates how to use the OAuth2 Client Credentials Flow in JavaScript to 
        obtain an Access Token and how to use the Access Token when calling the CodeProject API.
    </p>
    <input type="button" id="getArticles" value="Get Articles" class="btn" />

    <div id="results"></div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="app.js"></script>

    <script type="text/javascript">
        $(function () {

            $("#getArticles").click(function () {

                $("#results").html("");

                var data = SampleApp.GetArticles();
                if (data) {

                    var html = "<h3>The first " + data.items.length + " of " +
                             + data.pagination.totalItems + " items</h3><ul>";

                    for (i = 0; i < data.items.length; i++)
                        html += "<li><a href=\"" + data.items[i].websiteLink +
                                "\">" + data.items[i].title + "</a></li>";

                    html += "</ul>";

                    $("#results").html(html);
                }
                else {
                    $("#results").html("<b>Failed to Load Articles.</b>");
                };
            });
        });
    </script>
</body>
</html>

The JavaScript file create a SampleApp object with one public method GetArticles. This method requests an Access Token, if required, and then request the first page of Articles.

apps.js listing

var SampleApp = function () {
    var app = {};

    var clientApiKey = "JkOnJ9zIQ1vWvP3FvsJVx-3iOnSd-6a-";                                 // CodeProject Test API Key
    var clientSecret = "U_ZHCQackGJHW4-Jn4qfGce6JLV9qAKhJEGahyRHVpeYVWf_r8iSaSt4z6AZn8kC"; // CodeProject Test Secret
    var baseUrl       = "https://api.codeproject.com";
    var getTokenUrl   = baseUrl + "/token";
    var generalApiUrl = baseUrl + "/v1/Articles";                          // The URL of the API to call
    var appAuthToken;

    // define the public variables/functions
    app.GetArticles = getArticles;
    // ---------------------------------------------------------------------------------------------------------------------
    // General API calls (eg articles, message etc) require only the API Key and Secret.
    function getArticles()
    {
        getAccessTokenByPost();
        var returnedData;
        if (appAuthToken) {
            $.ajax({
                method:      "get",
                url:         generalApiUrl,
                contentType: "application/json; charset=utf-8",
                headers:     { 'Authorization': 'Bearer ' + appAuthToken },
                async:       false,
                success: function (data) {
                    returnedData = data;
                },
                error: function () {
                    // in a real app, you should check for a 401 and if so delete the Access Token
                    // so that it will reload on the next request.
                    alert("failed to get articles.");
                }
            });
        }
        return returnedData;
    }

    function getAccessTokenByPost() {
        // If we already have an access token, then just signal done, otherwise request a token
        if (appAuthToken) {
            alert("using saved Access Token");
            return;
        }
        else {
            var postData = {
                grant_type:   'client_credentials',
                client_id:     clientApiKey,
                client_secret: clientSecret
            };
            $.ajax({
                // Make a call to the protected Web API by passing in a Bearer Authorization Header
                method:      "POST",
                url:         getTokenUrl,
                contentType: "application/x-www-form-urlencoded",
                data:        postData,
                async:       false,
                success: function (data) {
                    alert("got Access Token");
                    appAuthToken = data.access_token;
                },
                error: function () {
                    alert("getting Access Token failed.");
                }
            });
        }
    }
    return app;
}();