Securing Your React App with Atlas App Authentication

Mastering MongoDB Atlas Web SDK — Part 1

Markandey Pathak
8 min readFeb 27, 2024
Mastering MongoDB Atlas Web SDK

MongoDB Atlas is a fully managed cloud database service provided by MongoDB. It allows users to deploy, operate, and scale MongoDB databases with ease, eliminating the need for users to manage infrastructure tasks such as hardware provisioning, setup, configuration, patching, and backups. MongoDB Atlas offers a range of features tailored for different use cases, including high availability, automated backups, security features, and performance optimisation tools.

One aspect of MongoDB Atlas is the Atlas App Services. This is a suite of services provided as part of the MongoDB Atlas platform to help developers build, manage, and deploy modern applications more efficiently. These services include User authentication and management, Schema management and access rules, Device sync, GraphQL, Serverless functions, HTTP Endpoints and much more. Atlas Device SDKs are available for various platforms like Kotlin, Swift, .NET, Java, Node.js, Flutter, React Native, C++ and Web.

Throughout this entire series, our focus will remain on the Web SDK, delving into how Atlas App Services can seamlessly integrate with Web Applications to construct modern, data-centric applications. By leveraging the power of MongoDB Atlas and the capabilities offered by the Web SDK, we’ll uncover innovative approaches to building robust and efficient web-based solutions.

Setting up the development environment

For this entire series, all you need is a web browser. We will be using

  • Glitch for our development
  • MongoDB cloud account to setup Atlas App Services

Creating a MongoDB cloud account

Establishing a MongoDB cloud account is straightforward. Just navigate to https://cloud.mongodb.com and sign in via your Google or Github credentials. Alternatively, you have the option to register using your email address if preferred.

Creating a MongoDB Atlas account

Upon account creation, it’s advisable to acquaint yourself with the User Interface. Initially, the array of configurations might appear overwhelming. However, fret not, as we’ll delve into them extensively as we advance through the series. For now, feel free to create a project and deploy a database to get started.

Creating a cluster

MongoDB Atlas provides a notably generous free tier that grants you 512 MB of storage, and it remains free indefinitely. This complimentary tier encompasses the majority of the services mentioned previously.

Opt for the M0 cluster tier, select your preferred provider among AWS, Google Cloud, and Microsoft Azure, and then choose a region nearest to your location for optimal performance. Provide a name for your cluster and proceed to click on the “Create” button. Your cluster will be created and deployed within a matter of minutes.

Upon the successful creation of your cluster, you have the option to create a user for accessing the MongoDB database. However, for the context of this article, this step is irrelevant. Instead, navigate to the “App Services” tab located at the top of the page as indicated below.

With our cluster now prepared, we can proceed to create our application. The application creation wizard provides boilerplate options to expedite the project setup. Choose the “Build your own App” option and then click on “Next” to proceed.

Enter a name for your application, select a data source (which will be the cluster created earlier), and proceed to click on “Create App Service” when you are prepared.

Each application is allocated a unique application ID, which serves as the identifier utilized by Atlas SDKs to establish connections with your application.

The App ID, being non-sensitive information, can be safely stored within your codebase. However, the actual security measures at the application level are configured through the App settings, which include specifications such as Allowed Origins or Allowed IP Addresses, along with Data Access Rules.

To regulate requests to our Atlas App Services App, we can define a list of permitted origins. This can be accomplished by accessing the App Settings section from the left-hand sidebar, where you’ll find the setting for Allowed Request Origins, as depicted in the screenshot below.

Creating a Glitch account

With our application configured, it’s time to commence building our web application. To get started, you can create a free Glitch account by visiting https://glitch.com. After logging in, you can access my boilerplate project at https://atlas-auth-boilerplate.glitch.me and simply click on “Remix” to begin working on it.

Glitch boilerplate project

Once you’ve remixed the boilerplate project, it will be cloned for you, allowing you to start building on it immediately. Take note of the preview pane within the Glitch UI and copy the preview URL, which in your case would be https://atlas-auth-boilerplate.glitch.me. This URL serves as your application URL. With our development environment fully configured, we’re now ready to commence building our web application.

Glitch preview pane

Objectives

To begin, we’ll set up the Email/Password authentication provider for our Atlas App. This will be followed by the construction of the Signup, Confirmation and Login screen to facilitate user registration. Finally, we’ll utilise the realm-web library to connect our Web Application to Atlas App Services.

Setup Email/Password authentication provider

To enable user registration/login using email and password, we must activate the Email/Password authentication provider in the Atlas UI. To do this, access your newly created Atlas Application and navigate to the Authentication option located on the left-hand sidebar.

Atlas App Services Authentication Providers

Click on the “Edit” button next to Email/Password from the list of providers. This action will direct you to the provider configuration page where you can enable and set up the provider. Configure the settings as follows:

  • Toggle “Provider Enabled” to Yes
  • Select “Send a confirmation email” as the user confirmation method
  • Set the “Email confirmation URL” to <your-glitch-url>/verify
  • Specify “Confirm your account” as the Email confirmation subject.
Enabling Email/Password authentication provider

After configuring the provider settings, click on “Save Draft” to save your changes. A banner will then appear at the top, prompting you to “Review Draft & Deploy” your modifications. This step helps prevent accidental alterations to your production application. Click on “Review Draft & Deploy”, and your changes will be deployed shortly.

Review Draft & Deploy

Building up screens

The boilerplate code includes several pre-built screens, but they are currently non-functional. To begin adding functionality to these screens, we must first create an instance of the App class exposed by realm-web. Update the useEffect function in your app.jsx file as demonstrated below (remember to replace <ATLAS APP ID> with your actual App ID):

useEffect(() => {
setRealmApp(new App("<ATLAS APP ID>"));
}, []);

The updated signup.jsx file under the pages directory should utilise realmApp to execute user signup. Upon the user entering their email and password and clicking the Signup button, we will invoke the realmApp.emailPasswordAuth.registerUser function. This function accepts email and password parameters and attempts to create a new user in your Atlas App. Handle the onClick event of the LoadingButton component as illustrated in the following code snippet:

<LoadingButton
classNames="btn btn-primary"
text="Signup"
loading={loading}
disabled={!email || !password}
onClick={() => {
setLoading(true);
realmApp?.emailPasswordAuth
.registerUser({ email, password })
.then(() => setSuccess(true))
.catch((err) => {
setSuccess(false);
setError(err.error);
})
.finally(() => {
setEmail("");
setPassword("");
setLoading(false);
});
}}
/>

Upon successful creation of the user account, the user will receive a confirmation email containing a link to verify their account. This step serves as a protective measure against potential misuse of your web application.

To handle the user confirmation task, we need to extract the token and tokenId parameters from the verification URL contained in the confirmation email. These parameters are appended to the URL specified while enabling the email/password authentication provider. Let’s update the pages/verify.jsx file with the following code to facilitate this process:

useEffect(() => {
realmApp?.emailPasswordAuth
.confirmUser({ token, tokenId })
.then(() => setSuccess(true))
.catch((err) => {
setError(err.error);
})
.finally(() => setLoading(false));
}, [realmApp, token, tokenId]);

This code snippet utilises the useEffect hook to trigger the confirmation process when the component mounts. It extracts the token and tokenId parameters from the URL and passes them to the realmApp.emailPasswordAuth.confirmUser function. Upon successful confirmation, the setSuccess function is invoked to indicate successful confirmation, while any errors are handled by setting the error state. Finally, the loading state is updated accordingly.

A user account is not active until first login. To enable users to log in, let’s update the onClick event of the LoadingButton component in the pages/login.jsx file. We’ll utilise the realmApp.login function and provide it with a Credentials object created using Credentials.emailPassword(). Here’s how you can update the onClick event:

<LoadingButton
classNames="btn btn-primary"
text="Login"
loading={loading}
disabled={!email || !password}
onClick={() => {
setError(false);
setLoading(true);
const credentials = Credentials.emailPassword(email, password);
realmApp
?.logIn(credentials)
.then(() => setUser(realmApp?.currentUser))
.catch((err) => setError(err.error))
.finally(() => {
setEmail("");
setPassword("");
setLoading(false);
});
}}
/>

Upon successful login, the context should indeed be updated with the realmApp.currentUser object. Additionally, the Header component should display the user’s email address along with a logout link.

Logged in User

Handling the logout process is straightforward with realm-web. The realmApp.currentUser object provides a logOut function to execute the logout action. Since we have set realmApp.currentUser in our AppContext, the Header component can easily handle the onClick event of the Logout link. Here’s how you can update the header.jsx file to implement this functionality:

const logout = useCallback(() => {
user?.logOut();
setUser(null);
}, [user]);

And there you have it! We have successfully implemented a complete Signup/Login flow using React and the realm-web SDK. With user registration, email confirmation, login functionality, and logout capability all in place, your application is now equipped with essential user authentication features. Great job!

Completed application can be viewed here and the source code can be access/remixed here.

As the curtain falls on this inaugural chapter, we stand at the precipice of greatness. Join us in the forthcoming chapters as we delve deeper into the realm of MongoDB data consumption and continue our quest for application excellence. Stay tuned for an enlightening journey into the realm of web application development with MongoDB Atlas!

--

--

Markandey Pathak
Markandey Pathak

Written by Markandey Pathak

Expert Engineer & Vice President @ JPMC | Programmer| Javascript Expert | Flutter Enthusiast | Avid Speaker

No responses yet