January 2017 - Posts

You can host an Ionic 2 Progressive Web App (PWA) pretty easily on Azure Web Sites (App Service).  If you aren’t sure where to get started, take your Ionic 2 project and add the browser platform if you haven’t already.

ionic platform add browser

Now, you can test it locally by running against the browser platform.

ionic run browser

Running it on Azure really is just a matter of copying your files to your Azure Web Site via ftp.  You can get the username and address to connect to from your App Service properties.  Connect to it and be sure you change to the /site/wwwroot folder.  This is where the files from your app will go.  To will upload your files from the platform/browser/www/build folder.  Before you copy your files though I recommend you do a production build with the --prod command.  This will make the size of your JS files considerably smaller.

ionic run browser --prod

Now copy your files to the FTP site and go to the corresponding URL in your browser.  Your app should be working there. 

There are a few mime types that you need to configure so that the Ionic fonts and any other files get served by IIS properly.  You do this in by creating a web.config.

<?xml version="1.0"?>
 
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
      <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
    </staticContent>
  </system.webServer>
</configuration>

If you are working with DeepLinker, you may consider using a path-based location strategy instead of the standard hash based.  This effectively removes the hash (#) symbols from all of your URLs.  However, additional configuration will be required.  That’s because IIS hosting your site in Azure will give you a 404 error when you go any of the routes you have defined.  You need to redirect your routes to index.html to work. I have found that the routes in the web.config listed below pretty well.  If you are using query strings you might run into issues with these routes though so you may need to do some additional configuration.

<?xml version="1.0"?>
 
<configuration>
  <system.webServer>
    <staticContent>
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
      <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
    </staticContent>
    <rewrite>
      <rules>
        <clear />
        <rule name="AngularJS Routes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Running your PWA in Azure works a little bit differently, but once you have it configured, it’s a good solution.  If you run into any issues, turn on diagnostic logging in Azure and watch the log streaming to see what is happening.  Be on the lookout for scripts and CSS files returning a copy of index.html instead of what they are supposed to.  You can easily verify this from the developer tools of any browser.

If you have used Azure App Service, you will have loved how easy it is to set up authentication to providers such as Azure Active Directory and Facebook.  It lets you get started with a single line of code.  You can literally login with a single line of code like the following:

client.login('aad').then(results => {     // successful login 
}, error => {     // login error 
});

This will give you an id_token that you can then turn into a access_token by calling the /.auth/me endpoint with a REST call.  However, that access_token won’t have access to anything even though you configured App Service to use an App that has requested specific permissions.  CGillum from Microsoft pointed me in the right direction with his post to access the Azure AD Graph, but the Microsoft graph required some tweaks.

You start by going to the Azure Resource Explorer.  However, this assumes you have already configured your App Service app to use your particular Azure AD Application that you are creating.  Find your app service app in the hierarchy and then open /config/authsettings and click Edit.  If you haven’t set your clientSecret yet, you can do so now (although I am not 100% sure it’s required).  However, the key parameter is to set additionalLoginParams with the following JSON array. 

["response_type=code id_token",  "resource=https://graph.microsoft.com"]

This tells /.auth/me to give you the proper access_token when you call it.  You can also get a refresh token this way at the same time.  Once you have made the changes click the PUT button to send the changes back to the service.  Your should look something like this.

Screen Shot 2017-01-12 at 9.19.14 AM

Now, when you login again and call the /.auth/me endpoint, you’ll get additional data including an access token that works with Microsoft Graph.  If you have logged in before with this particular username and app, you will want to sign out and log back in again to make sure the permissions that you specified in your application get granted.  You may need to add the query string parameter prompt=consent on the login page to get it to prompt you for the new graph permissions.  Otherwise, you’ll get an access token that won’t work with the Microsoft Graph.

Screen Shot 2017-01-12 at 9.12.36 AM

As you can see in the screenshot above, the object returned has a lot more information in it than before.  There is nothing particular sensitive in this screenshot either since this is just a demo tenant.