Contents
- Introduction
- What you'll need to complete this tutorial
- Step 1. Set up the initial application
- Step 2. Modify the application code and deploy
- Step 3. Scale the application in IBM Cloud
- Step 4. Understand the test results
- Step 5. Add session persistence with Redis
- Conclusion
- Downloadable resources
- Related topics
- Comments
Scale single sign-on with App ID for your Node.js cloud apps
Use Redis to scale authentication for apps using the IBM App ID service
In this tutorial, you will learn about implementing scalable Node.js applications when you are using the App ID service. This IBM Cloud service allows you to add authentication to your mobile and web apps and protect your APIs and back-ends running on IBM Cloud. App ID provides authentication with email/password through a scalable user registry or you can add social login, so that users can sign in with their Facebook or Google credentials. With App ID, you can also host user profile info that you can use to build engaging experiences.
Successful cloud-scale application design requires planning for how to correctly achieve horizontal scaling in application components and services. For the tutorial, you create a Node.js getting started application in IBM Cloud that is modified for App ID. The application works well with a single instance. But you'll see that it demonstrates unreliable behavior when the app is scaled to two instances. Then, I explain what went wrong and take you through one implementation to fix it, with the help of the Redis Cloud service in IBM Cloud.
“To achieve optimal scaling, each process should be designed to be stateless and always persist data to a backing service available to all processes.”
What you'll need to complete this tutorial
- An IBM Cloud account
- A workstation with the following software installed:
- Git (to clone the base app repository)
- The IBM Cloud CLI version 0.6.5 or later.
- A text editor for making minor updates to the provided source code
When you run my demo app, sign in with the user name
clouduser@example.com
and the password
IBMcloud123
.
Step 1. Set up the initial application
Your first task is to create a simple Node.js application in IBM Cloud that uses the App ID service. You'll create a new app, add and configure an App ID service instance, and bind the service to the app.
- Log in to IBM Cloud, click Create Resource.
- Click Cloud Foundry Apps>SDK for Node.js.
- Specify a unique name for your app. For example, you could start the
name with
scaleApp ID
followed by a hyphen and then, to make it unique, add your initials and the date, as inscaleApp ID-tor1803
:Note: In the rest of this tutorial, replace
<your app name>
with the name you entered here. - Click Create. You can continue with the following steps while the app is being created.
- Go to the IBM Cloud Catalog and click App ID in the
Security services section:
- Keep all defaults and click Create. Wait for the service to be created and the dashboard for the service to start.
- On the left menu of the App ID dashboard, select Users to open the Cloud Directory.
- Click Add User.
- In the Add User dialog box, enter a user name and
password of your choice, along with the other profile attributes.
Click Save to add the user.
- Return to the Apps dashboard and click your application to open its overview page.
- In the application overview under Connections, click Create connection.
- Select the icon for the App ID service that you just created and click
Connect:
- If prompted to restage the application, click Cancel.
- After you connect the service, you will see the App connections panel with the App ID service icon.
Your initial app setup is complete.
Step 2. Modify the application code and deploy
In this step, you clone a GitHub project that has the Getting Started Node.js App configured to use App ID. You'll make a minor modification to the manifest to deploy it over the Cloud Foundry application that you created in Step 1.
- Open a command prompt on your local workstation and run this command:
git clone https://github.com/ibmecod/bluemix-scaleAppID.git <your app name>
- Update the
manifest.yml
file, replacing the apphost
andname
properties:applications: - name: <your app name> host: <your app name> memory: 128M
- Change the command-line working directory to the project directory and
log in to IBM Cloud with the IBM Cloud command-line tool:
bx login -a https://api.ng.bluemix.net
- Update and deploy your app in IBM Cloud by running:
bx app push
- Watch the staging messages from the
bx app push
command. After deployment, the app will start and you'll see a state ofrunning
for the app instance:
The app is now ready for testing.
Step 3. Scale the application in IBM Cloud
In this step, you test authentication for your app—first with a single app instance and then with an added second instance.
- In a new browser window or tab, open the URL for your application:
https://<your app name>.mybluemix.net
. Click the Log in button. - You will see the default App ID login screen. You can change the
authentication options that are available in the App ID login chooser
and also customize the color and the displayed logo by using the App
ID dashboard.
Enter the user name and password that you added to the Cloud Directory when you are configuring the App ID service and click Log in.
You get a greeting that combines the authenticated user name and the realm of the authentication — for example, "Hello, Cloud User!" — indicating that you authenticated successfully for this app instance. - Return to the IBM Cloud Apps dashboard to scale the application. Open the app overview, click the + button on the Instances dial to increment the instance number 2, and click Save.
- IBM Cloud starts the second instance. After a moment the instance
health will update with the new number of instances:
- Close the browser session that you used to test App ID and open a new
browser window or tab. Browse to
https://<your app name>.mybluemix.net
and click the Log in button. Authenticate to the App ID login screen. - Instead of the simple greeting, most likely you will see the login panel appear again. Or you might see the simple greeting, but if you click reload one or more times, you end up back on the login panel. If you experiment a little, you might also observe a successful login, where the app returns to the home page without any notification or acknowledgement of the successful login. In short, the application behavior has become unpredictable.
Step 4. Understand the test results
The simple app had no authentication issues with a single instance, but two instances are a problem because this app doesn't follow the twelve-factor app methodology. Specifically, it violates factor 6: "Execute the app as one or more stateless processes."
This unintentional failure is a by-product of how Node.js apps in IBM Cloud
use express-session
middleware and Passport in implementing
the session interface that was used with OpenID Connect. By default, the
express-session service stores session data in-memory, so it's available
to only one of the two instances. This problem actually affects any
application that is trying to use HTTP sessions with express-session so
the solution we describe here works for all of those other applications,
too.
This diagram illustrates how data for a session is only available to Instance 0 in the app:

What's the solution? Factor 6 goes on to say, "Any data that needs to persist must be stored in a stateful backing service, typically a database." The express-session documentation on GitHub lists several compatible backing stores. You'll implement this persistence by using Redis, which provides an in-memory key-value cache. This change will move session data for express-session out of the instance memory and into a persistent store available to all instances:

Step 5. Add session persistence with Redis
The Redis Cloud service in IBM Cloud is hosted in the same cloud environment as your app, minimizing response time for accessing this backing service.
- In IBM Cloud, navigate to the catalog and choose Redis
Cloud from the Data & Analytics category:
- Select the 30MB Free Plan from the Pricing Plans list.
- Click Create to add the service.
- Click Restage to complete adding the service to your app.
- Return to the Apps dashboard and click your application to open its overview page.
- In the application overview under Connections, click Create connection.
- Select the icon for the Redis service that you just created and click Connect.
- Click Restage to complete adding the service to your app.
- In your local copy of the application source code, update the
dependencies
section in package.json by adding a comma on line 25 and two more entries:"passport": "^0.4.0", "connect-redis" : "^3.3.0", "redis" : "^2.8.0" },
- In server.js, add
redis
andconnect-redis
to therequire
section, appending after line 6:const passport = require("passport"); const redis = require('redis'); const RedisStore = require('connect-redis')(session);
- After line 112 , add code to obtain the
configuration details for the Redis Cloud service from the environment
and connect to the service:
// additions for App ID support // get configuration for redis backing service and connect to service var redisConfig = appEnv.getService(/Redis.*/) var redisPort = redisConfig.credentials.port; var redisHost = redisConfig.credentials.hostname; var redisPasswd = redisConfig.credentials.password; var redisclient = redis.createClient(redisPort, redisHost, {no_ready_check: true}); redisclient.auth(redisPasswd, function (err) { if (err) { throw err; } }); redisclient.on('connect', function() { console.log('Connected to Redis'); });
- In the
app.use (session (...
statement around line 130, add an option to use Redis as the store for the session:app.use(session({ store: new RedisStore({ client: redisclient }), secret: '123456', resave: true, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session());
- Save app.js and package.json if you haven't done so already.
- From the command line, update the app:
bx app push
- After the app starts, use the Cloud Foundry
logs
command with therecent
option:bx app logs <your app name> --recent
- Check for a message that the app connected to Redis on startup:
- The manifest.yml file does not specify a number of active instances, so the app restarted with two instances and the sample output is from instance 1.
- Go back to your app at
https://<your app name>.mybluemix.net/
and repeat the login test from Step 3.
Success! Now the app works correctly with two (or more) instances.
Conclusion
In this tutorial, you created a simple app that uses the App ID service for
IBM Cloud and then tested the app with one and two instances running. With
two instances, the app was unreliable because the Node.js
express-session
middleware defaults to a local in-memory
store.
You fixed the problem by adding a persistent store for
express-session
sessions by using the Redis Cloud service in
IBM Cloud. Although it's a good fit for this tutorial, the Redis Cloud
free plan has no liability/SLA. For production use, consider the Compose for Redis service or one the services from Redis Enterprise
Cloud.