30 Days of Zumo.v2 (Azure Mobile Apps): Day 7 – Refresh Tokens

So far in this series, I’ve look at the following:

Today I’m going to cover a common problem within token-based authentication. Every token that is given out has some in-built security – an expiry time. How do you deal with the expiry of a token? Facebook expires tokens once every 60 days (not exactly a problem). However, most authentication providers are much smaller – Azure Mobile Apps, Azure AD and Google all use 1 hour – a number in common with a lot of providers. Some providers use very short times (miiCard, for example, uses 2 minutes, which is crazy as it practically guarantees you need to do two API calls instead of 1 to do something). To ensure that the user is still authenticated, identity providers implement a refresh token mechanism. Today, we are going to look at integrating refresh tokens into our client and server authentication flows. If you are using Custom Authentication, then this is another topic you have to deal with this yourself. Sorry – there are no generalized rules here.

Refresh Tokens

You’ve logged in (somehow) and received a token from Azure Mobile Apps. Here is a little secret. It expires after 1 hour. Actually, that’s not much of a secret. It’s kind of well-known. What isn’t well known is how to deal with it. The short version of this is that there is an endpoint available for refreshing all your authentication tokens at the same time. The response is a new token. You have to submit the old token. Some of the Azure Mobile Apps client SDKs will include a method InvokeApiASync() that does this for you. The Apache Cordova Plugin doesn’t, but it does have a _request() method that I can use instead. Let’s start by adding a button to interactively call the refresh API:

    function initializeApp() {

        // Replace the wrapper with the main content from the original Todo App
        var content =
              '<div id="wrapper">'
            + '<article>'
            + '  <header>'
            + '    <div id="title"><h2>Azure</h2><h1>Mobile Apps</h1></div><div id="rt-title"><button id="reftoken">Token</button></div>'
            + '    <form id="add-item">'
            + '      <button id="refresh">Refresh</button>'
            + '      <button id="add">Add</button>'
            + '      <div><input type="text" id="new-item-text" placeholder="Enter new task" /></div>'
            + '    </form>'
            + '  </header>'
            + '  <ul id="todo-items"></ul>'
            + '  <p id="summary">Initializing...</p>'
            + '</article>'
            + '<footer><ul id="errorlog"></ul></footer>'
            + '</div>';

        // Refresh the todoItems

        // Wire up the UI Event Handler for the Add Item
        $('#add').on('click', addItemHandler);
        $('#refresh').on('click', handleRefresh);
        $('#reftoken').on('click', handleTokenRefresh);

Line 62 adds the button – I can make some CSS to push the entire DIV right and clean it up. Line 82 adds a click handler for the button. This is fairly standard HTML and JavaScript code so far. Let’s take a look at the event handler:

     * Event Handler for clicking on the token button
    function handleTokenRefresh(event) {

        client._request('GET', '/.auth/refresh', function (error, response) {
            console.error('refresh error = ', error);
            console.info('refresh response =  ', response);

Configuring OpenID Connect “Hybrid Flow”

Spoiler: It doesn’t work

I got a 400.80 Bad Request response from the server. That’s because I have not configured the Azure AD service to use refresh tokens. App Service Authentication / Authorization express configuration uses the OpenID Connect “Implicit Flow”, which is convenient because it doesn’t require a secret key, but has the disadvantage of not allowing you to get a refresh token. To get a refresh token, I need to configure the OpenID Connect “Hybrid Flow”.

Log into the Azure Portal, select Browse> and then Active Directory (it will be at the top)

Quick Tip Click on the star next to Active Directory – it will make the link appear in the side bar so you don’t need to click on Browse.

After the directory appears (you may need to click on it if you have more than one), click on the APPLICATIONS tab, then click on your application followed by the CONFIGURE tab.


Scroll down to the keys section. Select Duration = 2 years in the drop-down, then click on Save. (Don’t forget to come back and re-issue the key before the 2 years are up!) Copy the key that is generated after you saved.


Now, go back to the Azure Portal, select All Resources or App Services, then select your app service. Mine is 30-days-of-zumo-v2. Click on Tools, then Resource Explorer, then Go


You will get a new tab pointing to your site inside of https://resources.azure.com – an awesome site for viewing all the settings. Expand config and then authSettings:


Because this is a dangerous place, it’s set to read-only mode. Click on the grey Read/Write box at the top of the screen, then click on Edit next to the PUT button. I need to set two things. Firstly, the key that I created in the Azure AD portal needs to be copied into the clientSecret field as a string. Secondly, I need to set the additionalLoginParams to ["response_type=code id_token"], like this:


Note: Client Secrets and keys should be kept secret. I re-generated mine immediately after these screen shots were made.

Once you are happy with your edits (double-check them as they are impacting your site significantly), click on the PUT button at the top. It’s a good idea to put the interface into Read-only mode after you have made the edits – this prevents accidents from happening.

You’ve now configured a minimal Hybrid Flow. Note that this is the same flow you would need in order to access the AAD Graph API. However, there are a couple of extra steps. Refer to this blog post for more details.

The Refresh Response

Now that I’ve got the configuration done, my application will run again and will actually get a response. If you run the client with the logging, you will notice that error is null (indicating no error) and response is a standard XmlHttpRequest object. The _request() method is an under the covers method and isn’t meant to be run directly. Looking at the response from the server in the Network tab, I see the following:


The authenticationToken is the new token that I need to store in the client.currentUser.mobileServiceAuthenticationToken (note that capitalization changes between Client SDKs to conform to the client conventions). I can now deal with the refresh token thusly:

     * Event Handler for clicking on the token button
    function handleTokenRefresh(event) {

        client._request('GET', '/.auth/refresh', function (error, response) {
            if (error != null) {
                console.error('Auth Refresh: Error = ', error);
                alert('Authentication Refresh Failed');
            } else if (response.status !== 200) {
                console.warn('Auth Refresh: Status = ', response.status, response.statusText);
            } else {
                var data = response.response;
                client.currentUser.mobileServiceAuthenticationToken = data.authenticationToken;
                console.info('Auth Refresh: New Token Received and stored');

How to use Refresh Tokens

Of course, handling refresh tokens in an interactive way is definitely not the way to go. This is meant to be a hands-off approach to dealing with refresh tokens. My personal favorite is to write a method that returns a Promise and deals with it all for you:

  1. If you are not authenticated, then call the authenticate routine – resolve the Promise when authenticate returns successfully.
  2. If you are authenticated and it’s been more than 30 minutes (for example) since the last refresh, refresh the token then resolve the Promise when the refresh returns successfully.
  3. If the refresh fails, call the authenticate routine and resolve the Promise when authenticate returns successfully.

In this way you can use the authenticate-or-refresh method like this:

// pseudo-code only - do not use this as is
authenticateOrRefresh().then(() => {

For the purposes of this topic, I’ve just checked in the interactive refresh code. You can get it from my GitHub Repository.

What about Custom Authentication?

If you are using a third-party identity provider, then you will need to do the same sort of logic against the third party identity provider. You can read about the process for Auth0 on their site, for example. The underlying process will pretty much be the same, however. Configuration and URLs or SDKs will differ. Understand what it takes to get a refresh token and how often you need to request one.

Next Steps

We will be leaving our review of authentication in Azure Mobile Apps now. I recommend you follow Chris Gillumhis blog contains lots of additional information on the authentication system used by Azure App Service. In fact, this blog post could not have happened without him. If he hasn’t written about it, then just ask.

In my next article, I’ll move onto table controllers. We kind of got a taste of table controllers in the last article, but I’ll be going much deeper next.