Desktop App – How to Run the Code Sample

Background

The Desktop Code Sample Overview Page describes what we will build, so let’s get it running. This section will repeat many of the same steps from the earlier SPA Code Sample Setup.

Step 1: Add Domains to your PC

First go to the hosts file on your local PC, which will exist at one of these locations:

OS Path
Windows c:\system32\drivers\etc\hosts
Mac OS / Linux /etc/hosts

Add entries as follows to represent our domains:

  • 127.0.0.1  web.mycompany.com
  • 127.0.0.1 api.mycompany.com

Step 2: Use Okta as an Authorization Server

Go to https://developer.okta.com and sign up to get a developer account, after which you will receive an email to activate your account.

You will then get your own Authorization Server, which you can log into at  an Admin URL such as this: https://dev-843469-admin.oktapreview.com.

Once logged in, browse to API / Authorization Servers and view the default item that has been automatically created:

The above URL is what we will use in our Code Sample, and in my case the value is https://dev-843469.oktapreview.com/oauth2/default.

Step 3: Register OAuth Applications

In Okta we must add trust entries so that our applications can act as OAuth Clients and call the Authorization Server.

First register a Service Application for our API and note that the key OAuth settings are the client_id and client_secret:

Next register a Native Application and note that the key OAuth settings are the client_id and the redirect_uris:

About Loopback Redirect URIs

According to OAuth Standards for Native Apps, Authorization Servers should allow a Single Loopback URL such as http://127.0.0.1 to be registered, then accept redirect URLs from any port at runtime.

At the time of writing this seems to be a Future Okta Backlog Item so I had to register all possible URLs that we will use for our Desktop Code Sample.

Step 4: Configure Session Times

In Okta, go to API / Authorization Servers / Default / Access Policies / Default Policy Rule / Edit and set details as follows:

  • The user session is represented by the refresh token
  • Refresh tokens last for 12 hours
  • Access tokens are short lived and expire every 30 minutes
  • The refresh token will be used to silently renew access tokens

Step 5: Download Code from GitHub

The project is available here, consisting of a UI and API component. It can be downloaded / cloned to your local PC with this command:

  • git clone https://github.com/garyarcher36/authguidance.desktopsample1

Step 6: View Code in an IDE

I use Visual Studio Code on Windows, Mac OS and Fedora Linux, since it is cross platform and lightweight.

Select ‘Open Folder’ and browse to the AuthGuidance.DesktopSample1 folder, to view the code for both UI and API with syntax coloring:

Step 7: Update Configuration

Both the Desktop App and API have configuration files. In a real world app these would typically be delivered by your Continuous Delivery process.

For the Desktop App you will need to update the configuration to match your Authorization Server’s Base URL and OAuth Client Id:

Note that our Desktop Sample specifies the following details that differ from that of our SPA:

Setting Description
Loopback Port Range Corresponds to our Okta registered URIs
Login Success Page Where to send the browser after a successful login
Login Error Page Where to send the browser after a failed login
Offline Access Scope A scope needed to get refresh tokens

For the API you will need to update the configuration to match your OAuth Server Base URL and the API’s Client Id + Client Secret:

Step 8: Install Node JS if Required

Go to the Node JS Web Site and run the installer for your operating system.

Step 9: Install Desktop and API Dependencies

From both the desktopapp and api folders run ‘npm install’, which will download dependencies, including Electron:

Step 10: Configure SSL for the Code Sample

Next install the below root certificate used by the API to your operating system, as described in Root Certificate Deployment.

Step 11: Start the API

From the basicapi folder run ‘npm start’ to run the API, which will listen on port 443. If other system components are listening on port 443, such as IIS or Apache, stop them temporarily.

Note that on Windows you may need to use an administrator user and on Mac OS or Linux you will need to run this command:

  • sudo -E npm start

Browse to the following URL to get data and verify that you get an Unauthorized response:

In production you would run your API as a low privilege user, and there are various ways to enable this. Our objective though is just to enable real world HTTPS traffic on a developer PC.

Use Alternative Ports if you prefer

My preference is to use the Standard SSL Port 443 allowed by company firewalls. If you prefer to use an alternative port such as 3000, change the host names in Okta and the above configuration files:

  • http://web.mycompany.com:3000
  • http://api.mycompany.com:3000

Step 12: Build the Desktop App

From the desktopapp folder run ‘npm run build’ to build the Electron App:

The TypeScript code will be transpiled to Javascript and output to a built folder that is referenced in the index.html file:

Step 13: Run the Desktop App

From the desktopapp folder run ‘npm start’ to run the Electron App:

This will invoke the Electron executable due to the following command in the package.json file:

About Electron Executables

When running ‘npm start‘ we can use operating system tools to see that a couple of instances of the Electron executable are running, which point to our application files on disk:

We would build the Electron app into an executable before deploying to real users and we can do this with ‘npm run pack‘:

You can then run the type of deployed executable that would be delivered to your end users:

Step 14. Get Node JS SSL Working

You are likely to receive SSL errors when the Desktop App calls the API, due to untrusted root certificates. As a quick fix you can edit package.json for the API and Desktop App to disable Node SSL errors:

  • cross-env NODE_TLS_REJECT_UNAUTHORIZED=0

The API’s package.json will then look like this:

The Desktop App’s package.json will then look like this:

Once you are up and running, a less hacky option is to Add Root Certificates to Node JS via the NODE_EXTRA_CA_CERTS environment variable.

Step 15: Run a Desktop App Login

The first Electron screen we will see is the login screen. We need to show this every time we redirect the user to the system browser to log in:

When Sign In is clicked we give the user some visual progress in the Desktop App:

The System Browser is invoked and the user prompted to login to Okta. Note that browser features such as Password Autofill work nicely:

However, rather than logging in, close the browser on the first attempt. We will ensure that our Desktop App copes with this resiliently.

Next click Sign In again, and login to the second browser instance. After login the System Browser is redirected to a custom company web page:

The Electron App then receives the login result, gets tokens and can securely interact with its API and render the resulting data.

Step 16: Run a User Session

We can then use the UI to simulate session related events that may occur in your desktop apps. We will drill into these operations in the next blog post:

  • Access token expiry
  • Refresh token expiry
  • Explicit user logout

Note that our Desktop App now has a Long Lived Credential and we need to think about how our UI will securely deal with it.

At the time of writing the Desktop App only stores tokens in memory, so that if we use the Electron reload options in the default menu, tokens are lost and the user has to log in again:

Where Are We?

We have used our existing SPA to quickly build a Desktop App using Electron, which runs on all the main platforms.

We used the AppAuth-JS library to implement the Recommended OAuth Flow for a Desktop App – and zero changes were needed to our API’s code.

For the next post we will drill into OAuth messages for the Desktop Sample, which includes use of Refresh Tokens and PKCE Handling.

Next Steps