Happy Thanksgiving 🦃 to those who celebrate, and welcome to the next part of our Box content portal series. In today's tutorial, we will be looking at adding authentication to a custom portal. This is a semi-sequential tutorial series, so if you haven't followed part 1 or 2 — you are welcome to go back and do that! If you just want to read along, continue on.

🚨IMPORTANT NOTE 🚨

This tutorial and demo is for demonstration purposes only and is not production-ready. It lacks complete authentication and security measures, making it unsuitable for live environments without further development.

Solution Overview

In the previous parts, I showed a semi-customizable content portal. In this blog, we will be starting with a brand new code repository. This is due to the complexities of setting up a specific authentication provider. While I show Auth0 in this demo, you might have another IDP you are interested in. They are not all plug and play so to speak. They require some configuration, and every company or organization has their own security practices and policies.

In addition the authentication pieces, I've also refactored and reorganized the portal from parts 1/2. The look has also been refreshed.

Why Auth0

Before going further, I'd like to speak quickly on why I choose to use Auth0 as the example authentication provider for today's demo. At Box, we consider ourselves the best-of-breed for Intelligent Content Management. Similarly, Auth0 is widely considered a best-of-breed platform for developer-focused identity management and authentication, particularly recognized for its extensive flexibility, ease of integration, and focus on providing a smooth developer experience. I personally found their documentation to be above par, and their dashboard UI was easy to use and understand.

Infrastructure diagram

Here is a bird's eye view of how all the pieces of the solution work together.

None
Software architecture diagram of the content portal - tldraw

Walkthrough

Below, we will go through the steps to get the content portal setup locally on your machine, as well as deployed to Vercel.

Prerequisites

In order to complete the tutorial, you'll need the below. Some of the items, you will be able to reuse from parts 1 & 2 if you wish.

  • An IDE, like VS Code
  • Git
  • GitHub account
  • Github CLI — not required but highly recommended
  • Vercel account — suggested to login/signup with GitHub account.
  • Auth0 account — suggested to login/signup with GitHub account.
  • Box account — must use a Box wide unique email address if using a developer account. NOTE — only enterprise plus accounts will have access to Box AI functionality
  • Node 18.18.0 — install NVM to mangage and install other versions

Configure a Box Application

Since you created a Box Platform application in parts 1/2, you may use the same one here; however I'm going to adjust the setup instructions to match recommended content portal settings and scopes. You are welcome to create a new one if you wish.

  1. Create a New Application: Go to the Box Developer Console, click 'Create New App', choose 'Custom App', name your app, then 'Server Authentication with JWT'. Note — We are using JWT due to our use of app users.
  2. Set Application Scopes: Ensure the application is configured with the following permissions: app access only, read/write all files, manage users, manage AI (Note — Box AI is only available to Enterprise+ licenses and above), make api calls using the as-user header, and generate user access tokens. I choose the above scopes for the purposes of this demo; however, your specific needs may be different.
  3. Enter http://localhost:3000 in the CORS domains box. Click Save Changes in the top right.
  4. Generate a Public/Private Keypair: Click the button to generate a public/private keypair. Note this will require 2FA. You will have to set this up if you have done so before. A pop up will show you the steps to do so. After it is setup, you'll need to click through the keypair flow again.
  5. Download the JSON Config File: This file is automatically downloaded upon keypair generation. Keep this file close. We will need the information in this file in a future step. You are welcome to rename it as well.
None
Scopes set for the demo application
None
Enter CORS domain

Authorize the Box Application

Like always, a server authentication application will need to be authorized by the administrator of the Box instance. Follow the steps outlined at Custom App Approval to authorize the application in the Box Admin Console. Post-authorization, a service account email is assigned to the app. Anytime changes are made to the app's permissions and scopes, it will need to be reauthorized.

None
Box admin server application authorization popup
None
Where to find the service account email address

Fork & clone (or download) code repository

If you have installed and configured the GitHub CLI, you can run the following command to fork and clone the repository to your local machine. Make sure to run it in the directory you want the code to reside.

gh repo fork box-community/box-custom-portal-demo-auth0 --clone=true

You can also direct download the code to your local machine or you are welcome to clone it, but know that you will need to delete the .git file + switch the origin in order to deploy your own code to Vercel later on.

Once you have the code locally, change into the new directory and open it in your IDE.

cd box-custom-portal-demo-auth0
code .

Initialize dummy content

An init script and dummy files are included within the project to help automate some of the setup for running the demo.

Create an .env file based on the sample with this command.

cp .env_example .env

Open the newly created file. For this portion, we only need to fill out the Box JWT application variables. We will fill out the other variables later on. Copy the values from the JWT config file that was downloaded during Box Platform application setup. Paste in the values only — not the quotations.

If you haven't, install pnpm globally.

npm install -g pnpm

Also, while we are here, go ahead and install the Vercel CLI globally if you have not done so.

npm install -g vercel

In the terminal, make sure to switch to node v.18.18.0. You might need to run the install command if you haven't before.

nvm use 18.18.0

We are going to go ahead and install all the project dependancies now — since we need to use the Box Node SDK for the init script.

pnpm install

Once that is complete, run the following command to setup the dummy folder and files.

node  init.js

Once complete, you should these logs in the terminal. Make sure to keep those ids and link close, as we will need them in a later step.

None

If you look in the main Box web app, you'll notice that no folders or files appears. This is a great example of how Box security works! If you remember, the Box Platform application we setup used JWT with app access only. This means when we ran the init script and created content, it placed that content within the service account that represents the application not the user you are logged in with for the main Box web app.

If you would like to actually see the content that was created, you can do so from the content tab of the Box Admin Console. The init script created a Portal Demo folder within the root of the service account. Inside, there are three files: a logo image, a terms and conditions pdf and a dummy statement. We will use all of these in the subsquent steps.

None
Init dummy content

Before moving on, in your .env file you can paste in the terms and conditions file id as the REACT_APP_BOX_PREVIEW_FILE_ID variable. This file will be the same for all users.

Auth0 application setup

Now that we have setup the dummy content in Box, let's move on to configuring our authentication provide Auth0. Like noted above, you should have already setup an account. If you haven't, do that now. It is advised to signup with your GitHub account.

Once you get to the dashboard, select Applications on the left then click + Create Application.

None
Click + Create Application

In the pop-up, give the application a name — followed by selecting Single Page Web Applications. Then, click Create.

None
Select Single Page Web Applications

On the settings tab in the next window, find the Domain and Client ID. Copy both of those values into your .env file.

Scrolling further down the page, paste in the logo Box static link url you got from the init script earlier.

None
Insert logo static link

Even further down the page, find the text boxes for the Application URIs. Enter http://localhost:3000, http://localhost:3000/verify-email in the Allowed Callback URLs box, and enter http://localhost:3000 in the Allowed Logout URLs and Allowed Web Origins boxes. Then, click Save Changes in the bottom right.

Note — we will add the Vercel deployed URLs here later.

None
Insert application URIs

In the connections tab, switch off the Google option. In the real world, you could leave this on or add other connection options, but for the purposes of the demo today, we will flip it off.

None
Turn off google OAuth 2.0

On the left side, select Branding. Then, click Email Templates. In the options, scroll down and paste {{ application.callback_domain }}/login?success=true&message=Your%20email%20was%20verified.%20You%20can%20continue%20using%20the%20application. in the Redirect To field. Scroll down, and click Save.

None
Enter email verification redirect URL

While in the branding area, you are also welcome to change the colors of the login screen that will appear to users. This is optional.

None
Customize colors

Finally, go to Settings on the left. Scroll down, and insert Increo Financial as the Friendly Name and the static URL from the init script in the Logo URL field. Click Save.

None
Add logo and company name to settings

Auth0 actions setup

Now, we are going to set up three Auth0 actions (or serverless functions) for our application to use to create Box users, Box folders, and more! These are really cool, because once a user signs up or signs into the content portal, Auth0 can automatically do certain tasks ad-hoc, meaning you don't need to have a backend running all the time.

The three actions are Verify Email, Add Metadata to User and Create Box App User. Verify Email makes sure that a user's email is verified before allowing them to login. Add Metadata to User adds several Box ids from based on the user logging in. This allows Auth0 and Box to integrate seamlessly. Create Box App User creates a Box app user based on the user who signs up, as well as creates a folder tree and content for the new app user.

On the left side, click Actions -> Library. Then, in the top right click Create Action -> Build from scratch.

None
Click Create Action

Name the action Verify Email, and make sure the Trigger is set to Login/Post Login. Then, click Create.

None
Give the action a name

You can find the code for this function in the code repository that was forked and cloned under the auth0 directory. You will actually find the code for all three actions we are going to create.

None
Find the code samples

Copy/paste in the code for the action, and click Deploy.

None
Deploy Verify Email action

We are going to repeat these steps for both the addMetadataToUser and createBoxAppUser actions. For both of these two, you will need to add some secrets. After pasting in the code, you simply click add secret. Each action should get the following secrets BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_KEY_ID, BOX_PRIVATE_KEY, BOX_PASSPHRASE, and BOX_ENTERPRISE_ID. For the value, just like in the .env file, paste values only not quotations.

The createBoxAppUser action is a tiny bit different. The trigger for it should be Post User Registration.

None
Create Box App User action options

Also, this function has two extra secrets:PREVIEW_FILE_ID and DUMMY_STATEMENT_ID . You can grab those IDs from the output of the init script we ran at the beginning.

None
Create Box App User action

On the right side for both Create Box App User and Add Metadata to User, make sure to add box-node-sdk as a dependency. You can do this, by clicking the tiny box under the key on the left side.

None
Add box-node-sdk dependency

Once secrets and dependencies are added and the code is pasted in, don't forget to hit deploy.

None
Click deploy

Once complete, you should see three custom actions in your library.

None
All actions created

Now, we need to add them to a trigger. Then, the code will run based upon the actions users make. On the left side, click Triggers.

None
Open Triggers

Then, click post-user-registration. On the right side, select Custom and drag and drop the Create Box App User action into the trigger flow. Then, click Apply.

None
Create post user registration trigger

Click choose trigger in the top right to go back a screen and select post-login this time. Drag and drop Verify Email and Add Metadata to User into the trigger flow. Then, click Apply.

None
Create post login trigger

Run code locally

Back in your IDE in a terminal window, run the following command.

vercel dev

The first time you run this command — you will see the following options — which will setup the project in Vercel.

None
Run vercel dev

If you go to http://localhost:3000, should see the home screen. Click Sign In in the top right.

None
Local code running

This will redirect you the Auth0 login page. Click the Sign up bottom on the bottom. Enter an email address you have access to and a password that fits the requirements. You will then be led to this screen. You can close this tab. A new one will appear based on the link the email.

None
Verify email page

Find the email verification link in your inbox. It may be in your junk box.

None
Click verification link

Once you click the link, you will be sent back to the home screen. A green banner should appear saying the email is now verified.

None
Email verified

Click the sign in button on the top right, and sign in with the credentials you created. This will lead you to a dashboard similar to the below. The data in the dashboard is hard coded, but you could imagine where this information could come from other systems.

None
Logged in dashboard

You'll notice three options in the header: My Statements, Terms & Conditions and Upload Documentation. These represent three different Box UI Elements.

My Statements is the Content Explorer. This allows a user to in this case explore and view their statements. These statements were copied from the dummy statement from the code repository. It also allows them to view what uploads they have made with the upload option.

None
Content Explorer Element

Terms & Conditions is the Content Preview. This allows a user to view a specific file. You'll also notice this element has the Box AI modal option activated, meaning the user can make Box AI calls against this document.

None
Content Preview Element

Upload Documentation is the Content Uploader. This allows a user to upload documentation into their uploads folder. That content could then be used in some other workflow down the line.

None
Content Uploader Element

Deploy solution to Vercel

Now that the content portal is working locally, let's deploy it to the real world. In the Vercel dashboard you should see a new project for the code repository you ran locally. Open it. Click Connect Git repository. In the next screen, click GitHub and select the correct repository from the list.

None
Connect Git repository

In the general tab, scroll down and change the Node.js version to 18.x. Click Save.

None
Change Node version

In the environmental variables section, import the .env file from the local code. Click Save.

None
Import .env file

Now, we are ready to deploy it! In the terminal window of the code repository, run the following command.

vercel --prod 

Once complete, we need to configure a couple more things before we can test it. Go to the project home screen and grab the site's domain. It should look similar to this: project_domain.vercel.app. Copy that URL.

In the Box Developer Console, go back to the CORS Domains section of the application. Paste in the domain without the ending backslash. Click Save Changes.

None
Add domain to CORS Domains

In the Auth0 application configuration section, will want to add the same domain URL to the allowed callback/logout URLS and allowed web origins sections. Click Save Changes.

IMPORTANT — Make sure the deployed domain URL goes first in the list. Since we are using one application for both the local and production deployment in this demo the email verification will break if the public domain isn't first. Similarly, if you go back to running the local code, you will want to flip them in the text box.

None
Add URLs

After this, if you go to the domain URL, you should see the home page.

None
Deployed content portal

Live deployment

If you have made it this far — congratulations! If you stumbled along the way or are just reading and would like to test out the portal in the real world, you can find it here.

Please note that this link leads you to a deployed version that isn't completely private. Do not upload any content to your user account that you don't want to be public. Also, if abuse or bad actors appear, this live link may be shut down. You will need to signup with an email that you can verify.

Closing Thoughts

Adding authentication to the portal, while a bit challenging, gives you the security and flexibility to create more secure areas of the user experience. While I showed connecting Auth0, you could connect any authentication provider of your choosing with some code updates. In terms of authentication enhancements, you could use Box's built in token store methods to further enhance security by using a custom token database.

Whether you are using this blog as the jumping off point for your own portal development or just reading along, know that we have made using Box as the content layer for your web experiences as simple as possible. Stay tuned for more Box UI Elements enhancements coming soon.

I wish you warm thoughts during this fall and winter season. Until next time, happy coding!

Resources

Code repository

Box UI Elements

Auth0 developer documentation

Vercel developer documentation

As always, if you have any feedback for the Box Developer Relations team, feel free to drop us a line on the developer forum.