JSS and OKTA: Blog 2 – Login via embedded OKTA Form (August RELEASE)

This blog post is based on the OKTA samples @ https://developer.okta.com/quickstart-fragments/angular/default-example/ and the OKTA sign in widget that can be integrated into the page.

The branch mentioned above contains a working example that I will now run through in the rest of this blog. Once up and running your should get a login embedded into our JSS application that allows us to login via OKTA.


Overview

Firstly lets have a quick run through of the changes we made to the first blog in order to integrate the widget.

  1. OKTA configuration settings
    • These are stored in a settings file in the root of the JSS application: jss-okta-config.json
    • All settings to do with our OKTA instance can be added in here.
  2. Create the placeholder component to contain the widget
    • In JSS we scaffold up a new component
    • src\app\components\okta-sign-in\okta-sign-in.component.ts
    • Have a look at https://github.com/TomTyack/jssokta/blob/feature/okta-sign-in-widget/JSS/src/app/components/okta-sign-in/okta-sign-in.component.ts
      1. ngOnInit()
        1. Note how the code dynamically imports the OKTA sign in widget.
        • import('@okta/okta-signin-widget')
        • This is necessary as the library contains a reference to window. Which will break our Server Side code if imported normaly.
        • So in order to workaround this flaw we dynamically import the library only after verifying that this code is running client side.
      2. detectTranslationLoading()
        • Wait for the dictionary service to be loaded so that we can inject the Dictionary into the form.
      3. bootupSignin()
        • Initialise the OKTA widget configuration, inject labels and URLS
      4. injectWidgetPhase()
        • Render the widget
    • This contains the widget code and the has a matching from end HTML template in Angular.
      • The HTML file contains the following important tag
      •  <div id=”okta-signin-container”></div>
  3. Add the component to the /login route
  4. Adjust the navigation to include a new button for the widget
  5. Dictionary additions

Demo Video

To show you a video of this JSS example in action take a quick gander at the following video:


Demo Installation

  1. Clone the Repository
  2. Deploy the application. Follow the same instructions from the first blog. <<< UPDATE LINK
  3. Run the application. Follow the same instructions from the first blog. <<< UPDATE LINK
  1. Click on the “Login Embedded” link in the navigation
  2. Login to OKTA (if not already) using the details you registered with.
  3. You should arrive back on the profile page
  4. undefined
  5. Success!! hopefully 🙂
  6. Inside the OKTA Dashboard is a handy log that shows all login activity. This is a great way to see what is going on. Screenshot shown at the bottom.
    • undefined

Summary

That concludes the run through of how to integrate the OKTA Angular SDK and Embedded Widget into Sitecore JSS. OKTA is a leader in user authentication management and having the ability to integrate into our JSS applications is an exciting prospect. I hope this example is of use to you and your teams if your considering the same technology mix.


JSS and OKTA: Blog 1 – Login via External OKTA Form

This blog post is based on the OKTA samples @ https://developer.okta.com/quickstart-fragments/angular/default-example/

The OKTA samples makes use of the OKTA Angular SDK and allows you to set up a development OKTA cloud instance for testing the code.

For this blog I have integrated the OKTA example into the Angular JSS starter repository to for a new repository to accompany this blog. https://github.com/TomTyack/jssokta

This repository contains a working example that I will now run through in the rest of this blog. All you need to do is sign up for your own developer sandbox (OKTA) instance using a dummy user and test it out.


Overview

Firstly lets have a quick run through of the changes we made to the original examples in order to integrate them with the angular JSS application.

  1. OKTA configuration settings
  2. Provide the Login and Logout Buttons
  3. Create the Callback Handler
    • The callback handles integration in JSS takes place inside: src\app\routing\routing.module.ts
    • JSS Example: https://github.com/TomTyack/jssokta/blob/master/JSS/src/app/routing/routing.module.ts
    • In this case I made the route: /implicitcallback
    • Importantly the route must be added at the top of the list so that JSS routing doesn’t hijack the route before our OKTA module gets a chance. I spent a little while scratching my head over this one when I originally added it the bottom of the route config.
  4. Update your NgModule
    • This requires a little bit of adjustment from the original example.
    • Module integration is done via: src\app\app.module.ts
  5. Use the Access Token

Demo Video

To show you a video of this JSS example in action take a quick gander at the following video:

Note: In the video I started off the demo by running in Disconnected mode with localhost. Surprisingly this worked and it redirected back to the connected app domain. In reality a better test would have been to start on the same domain in integrated mode. I’m not sure that you could run this test end to end in disconnected.

Demo Installation

  1. Clone the Repository
  2. Sign up for an OKTA developer account
    • https://developer.okta.com/signup/
    • When it asks you what sort of application you want just click “Do this later”.
    • Confirm your email address and fill out the security questions and change your temporary password.
  3. In the top navigation withing the OKTA Dashboard
  4. Back in the JSS OKTA Repository (open it in VS Code or your editor of choice)
    • From the command line run: npm install
    • Open the file: jss-okta-config.json (in the root of the JSS Application)
      • issuer: Swtich out “INSERT-OKTA-ID” with the relevant ID from the same domain your viewing the OKTA portal in.
      • redirectUri: Replace ‘jssokta’ with ‘jss.okta.portal’ or whichever domain you set.
      • clientId: Found on the application > General tab. About 20 characters long.
  5. IIS
    • OKTA requires us to be running a domain with https, as such it makes it difficult to test this out in Disconnected mode.
    • Setup a Sitecore instance and make sure JSS is installed.
    • Add your new domain to the local hosts file and make sure its mapped to 127.0.0.1
    • Add the new domain to your Sitecore instance in IIS and make sure it capable of HTTPS. Use the developer certificate as a default.
  6. Back in the JSS OKTA Repository
    • Got to sitecore\config\JSSOkta.config
      • hostName: jss.okta.portal
    • From the command line run: JSS Deploy app
      • run through the setup as you would any JSS application so that it would connect with your Sitecore instance.
      • Sample config from my tests: See scjssconfig.json at the bottom of this blog
    • From the command line run: JSS Deploy config
    • From the command line run (again): JSS Deploy app -c -d
  7. Test out the deployed application:
    • Navigate to your domain: example: https://jss.okta.portal/ (must have SSL)
    • If prompted about the SSL security warning proceed and ignore. “Proceed to jss.okta.portal (unsafe)”
    • undefined
    • Click on the “Login” link in the navigation
    • Login to OKTA (if not already) using the details you registered with.
    • You should arrive back on the profile page
    • undefined
    • Success!! hopefully 🙂
    • Inside the OKTA Dashboard is a handy log that shows all login activity. This is a great way to see what is going on. Screenshot shown at the bottom.
      • undefined

Summary

That concludes the run through of how to integrating the OKTA Angular SDK in Sitecore JSS. OKTA is a leader in user authentication management and having the ability to integrate into our JSS applications is an exciting prospect. I hope this example is of use to you and your teams if your considering the same technology mix.


OKTA Setup Screenshots and Sample Config

I have included screenshots of all my OKTA settings below. As I know this can be difficult to diagnose at times.


scjssconfig.json

{
  "sitecore": {
    "instancePath": "C:\\inetpub\\wwwroot\\test.dev.local",
    "apiKey": "{FB95B118-E04F-4D5B-9465-01AE804A2F5A}",
    "deploySecret": "r6bnvuhv13beudhix1lxnej2ci38u0i6kxhnpy22i6ps",
    "deployUrl": "http://jss.okta.portal/sitecore/api/jss/import",
    "layoutServiceHost": "https://jss.okta.portal"
  }
}

Introduce YML Linting to your JSS Apps

Intro: This post shares how and why you might like to introduce a YML linter into the build process for your next Sitecore JSS project. Particularly if you are relying on the YML import process when building a new application. Shout out to David Huby (Solutions Architect) for introducing team Aceik to yaml-lint.

Why would you want to do this on a JSS project?

When running the JSS application and testing latest changes, we sometimes discovered some strange behaviour with dictionary items, or a page might not load properly.

A 404 page displayed after an invalid YML change was made

This can be caused by a small (incorrect) change in YML breaking individual routes. For example, lets say you have an incorrect tab or character in the wrong place. The YML syntax requires correct spacing and line returns to be valid but this is not always so obvious when done incorrectly. Sometimes only after you run the JSS application and test out the changes do you discover some strange behaviours or the page not loading properly.

To avoid this we found it handy to introduce a YML linter into the JSS build process. This solves the issue of someone making a small change to the YML files and breaking individual routes.

Here are the steps needed to introduce a YML linter into a node-based JSS project:

  1. Install yaml-lint (https://www.npmjs.com/package/yaml-lint)
  2. In the application root create the file .yaml-lint.json
  3. Update the package.json
    • Create a new script entry called yamllint
      • “yamllint”: “node ./scripts/yaml-lint.js”
    • Update the script called ‘build’
      • “build”: “npm-run-all yamllint –serial bootstrap:connected build:client build:server”,
  4. Download the following scripts file and place it in the /scripts folder
    1. https://github.com/TomTyack/jss/blob/feature/YAML-Linter/samples/react/scripts/yaml-lint.js

You can also see the pull request with the above changes at:

https://github.com/Sitecore/jss/pull/385/files

Demo

Sitecore Page Speed: Part 2: Inlining CSS into Helix

In part 1 of this Sitecore page speed blog, we covered off:

  • The Google Page Speed Insights tool.
  • We looked at a node tool called critical that could generate above the fold (critical viewport) CSS code that is minified.
  • We referenced the way in which Google recommends deferring CSS loading.

In this second part of the Sitecore Page Speed series, I am going to cover off how I would go about achieving this in my Sitecore layout.

Before we dive in I have committed the sample code for this blog into a fork of the helix habitat example project. You can find the sample here. For a direct comparison of changes made to achieve these page load enhancements, view a side by side comparison here.

Installation Steps:

MinimisedCode

  1. For each page that you want to render above the fold CSS we take the minimised code (we generated in the first blog) and put it on the page within the CMS.
  2. Inside the CMS we also create some new renderings in the common project.
    • These renderings are used in the default.cshtml layout.
    • They point to the CSS rendering code.
    • This wrapping technique provides the ability to cache the rendering so that the code in RenderAssetsService.cs does not need to be executed on every single page load.
    • Take note of the IDs of each rendering you will need to copy them over to the CachedRendering IDs shown in step 3 below.
  3. Update the default.cshtml layout with two key renderings.
    • One in the <head> tag that points to /Views/Common/Assets/InlineStyles.cshtml
    •  @*Inline Styles Rendering*@
       @Html.Sitecore().CachedRendering("{B14DA82E-F844-4945-8F31-4577A52861E1}", new RenderingCachingSettings { Cacheable = true, CacheKey = cacheKey + "_critical_styles" })
    • One just before the </body> closing tag that points to /Views/Common/Assets/StylesDeferred.cshtml
    •  @*Styles Rendering Deferred Styles *@
       @Html.Sitecore().CachedRendering("{F04C562A-CBF9-40CF-8CA9-8CE83FDF0BFA}", new RenderingCachingSettings { Cacheable = true, CacheKey = cacheKey + "_bottom_styles" })

StylesDeferred.cshtml  contains logic that will check for inline CSS on every page. If the page contains Inline CSS then the main CSS files will have their network download deferred until later. On the other hand, if the page does not contain any inline CSS then the main CSS files will be loaded as blocking assets. Doing so ensures that the page displays normally in both situations.

  • The cacheKey variable passed to our CachedRendering is simply something to identify the page as unique.  You could use the Sitecore context item ID or path for example.

If done correctly you should end up with pages that look normal even with the main CSS files deleted (only do this as a test). The CSS will no longer load via another network that blocks the page and your Google Page Speed rank should recieve a boost.