Complete Email Authentication with Next.js and Altogic
Tags: nextjs, altogic, webdev, javascript
Published: 2022-04-25 13:05:36

## Introduction
This article will cover email-based authentication basics using Next.js and [Altogic](https://altogic.com), a backend-as-a-service platform using its client library. This authentication method requires users to specify their email and passwords during sign-up. After signing up, users can log in to the application using their email and password. You can check the [source code](https://github.com/altogic/altogic/tree/main/examples/nextjs-email-authentication) and [demo app](https://altogic-nextjs-email-auth.vercel.app/).
By default, email verification is **enabled** in your **App settings → Authentication** view of **Altogic Designer**. If you would like to change this, you can **disable** “Confirm email addresses” in the **Authentication** view of **Altogic Designer**.

### How is the email authentication flow in Altogic?

1. Users sign up with their email and password.
2. A verification email is sent to the specified email address by Altogic.
3. Users confirm their email by clicking on the link in the sent email.
4. Altogic checks the token in clicked link and if valid changes the user’s email address to verified and returns an access token in the query string parameter of the redirect URL.
5. This access token is used to get a session token and users are directed to their profile page.

### Youtube Promo Video

You can check out the video below to see a live demonstration of our app.
{% embed https://www.youtube.com/embed/rlOTW_NuJzc %}

## Set up the backend

### Create an app in Altogic

First things first: To use Altogic, we need to create an app in Altogic. We can create an app in [Designer](https://designer.altogic.com/) easily. All you need to do is enter a name for your app.


![How to create an application in Altogic Designer.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mm2a9cjtg0dcnb0dp83r.png)

We need `envUrl` and `clientKey` to access our environment via Altogic Client Library. `envUrl` is specific to each environment, and Altogic initially creates one environment for you when you create your app. Here is how to get the `envUrl` from environment details page.


![How to get ehe environment url in Altogic Designer.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmuaxdconjc0clvu6btv.png)

We can get the `clientKey` by clicking on the **App Settings** button in the left-bottom corner of the **Designer** and clicking on the **Client library keys** section.


![Here, Altogic already created one for us, but we can create more client library keys and configure the permissions for different keys.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qa9n7d22i23josd8no5a.png)

### Users model
By default, **Altogic** creates a user model for you. You can customize it by adding different fields. Some of them are pretty advanced and customized, which is very handy.

## Set up the Frontend

### Install the packages
Before you start to use the `npx` command, make sure you have NodeJS installed in your development environment. Also, installing VSCode and some extensions might be better for faster development.
💡 You can visit [https://nodejs.org/en/download/](https://nodejs.org/en/download/) to **download**.
To get started, open the terminal and create a new Next.js project.

```bash
npx create-next-app@latest
```
Next.js will ask you to name the project. Name it whatever you want; I will use **“altogic-email-authentication”** for this example. Move to the folder just created and **install the Altogic Client Library**.

```bash
cd altogic-email-authentication
npm i altogic
```
Open the project in VSCode.
Install **tailwind CSS** and create `tailwind.config.js`

```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
Add the paths to all of your template files in your `tailwind.config.js` file.

{% embed https://gist.github.com/myerekapan/50b3f9672e889bf88fa38f46ec5d17f2 %}

Add the following directives to your `globals.css` file.

{% embed https://gist.github.com/myerekapan/eab86ff168b0ce5f2620b08f17f2f44c %}

Install **Font Awesome** to use the icons.
```bash
npm i --save @fortawesome/fontawesome-svg-core
npm install --save @fortawesome/free-solid-svg-icons
npm install --save @fortawesome/react-fontawesome
npm i @fortawesome/free-brands-svg-icons
```
Install **cookies-next** to set cookies for server-side rendering easily.
```bash
npm i cookies-next
```

Install **@headlesui/react** for styling.
```bash
npm i @headlessui/react
```
Update the `next.config.js` file to allow the Next.js Image component to load images from Altogic’s storage. `"c1-na.altogic.com"` value is retrieved from the `envUrl` which starts with `c1-na.altogic.com` in my case.

{% embed https://gist.github.com/myerekapan/54b0d80b8c5e725c0649fec518b8e02f %}

### Set up the environment variables

Environment variables are used to **secure** your secret keys, **reuse** them in different places and **reduce** production mistakes. Create a `.env.localfile` in the root directory of your application, open the file in your editor and paste the following. You can check more about environment variables in Next.js [here](https://nextjs.org/docs/basic-features/environment-variables).

{% embed https://gist.github.com/myerekapan/ae9bf63d0539388b41dbe9aaccaa677b %}

Replace `YOUR-APPLICATION-ENV-URL` and `YOUR-APPLICATION-CLIENT-KEY` with the `envUrl` and `clientKey` values you retrieved while setting up your backend.
Next, create a file to create the **Altogic Client Library** instance.
```bash
mkdir helpers
cd helpers
touch client.js
```
This creates a `client.js` file in the **helpers directory**. Open the file in your editor and paste the following.
{% embed https://gist.github.com/myerekapan/0b7e4a6ceec645966f4c24a4d0b00cb7 %}

Here, you need to enter the `envUrl` and `clientKey`. Optionally you can paste `signInRedirect` to redirect your users to the specified sign-in page in some cases. This works in a way that if users try to perform a session-required action while their session has been destroyed, **Altogic** redirects them to the `signInRedirect` route.

### Building our components

The next step is to create the components we’ll need for our application. You can also clone our example repository and use the components right away.
First, create a components folder with the `mkdir components` command. Let me walk you through the components we use for our app.

1. `Sign-in.js` and `Sign-up.js` file in `auth` directory. Those are the form components we use to sign-up and sign in our users.
2. `EmailConfirmResend.js` and `PasswordReset.js` file in `auth-redirect` directory. Those are the components we will show our users when redirected to the **our-domain.com/auth-redirect** route.
3. `AltogicBadge.js`, `Header.js` and `Layout.js` file in `layout` directory. Those are the components we use for our layout throughout the app.
4. `SessionListItem.js` ,`SessionList.js` , `ProfilePhoto.js`, `NameSection.js` , `ChangePassword.js` and `ChangeEmail.js` file in `profile` directory. Those are the components we use on the profile page.
5. `Button.js` , `Notification.js` and `ErrorMessage.js` file in `ui` directory. Those are the components we use many times to build our UI.

In the end, your components folder should look like this:


![Components folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxgxdvo3eb4skqetafam.png)

## Let’s start coding!

We have the backend and frontend setup ready. We can start integrating them now.

### Some UI components we use often

It is best to separate the logic of some of the components we use frequently and put them into a different folder to reuse.
**Button:**
{% embed https://gist.github.com/myerekapan/32a36ea81bd39d8bc57ef11b7a0d776d %}

**Error:**
{% embed https://gist.github.com/myerekapan/f4f21de8de694f36dd40f2ef5ed3bdbb %}

### Sign up functionality with Altogic

Altogic Client Library has a built-in function for creating new users with an email and password. You can check about it more [here](https://clientapi.altogic.com/v1.2.2/classes/AuthManager.html#signUpWithEmail).
**altogic**.auth.**signUpWithEmail** takes three inputs:

1. **email (mandatory)**
2. **password (mandatory)**
3. **name (optional)**
The code snippet handles the form input using the **signUpWithEmail** function.

{% embed https://gist.github.com/myerekapan/c317a26e9b7e400243a7ac9ff5b3dbdd %}

Our sign-up screen should look like this:


![Sign-up Screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pgalq8kdm78fwtjgc5fb.png)

This function will create a user object in your database with the provided **email**, **password**, and optionally **name** field. Altogic will send an email to the user’s email address.

### Redirect URL route

In **Altogic**, you can redirect your users to a predefined route for some actions.

1. When the user is successfully authenticated using an oAuth provider or a magic link, they will be redirected here.
2. When the email confirmation link is clicked, they are redirected to this route.
3. When a user changes their email, if the email confirmation setting of the app is enabled, an email is sent to them. After the user clicks it, they will be redirected to this route.
4. When a user recovers their password, they are redirected to this route.

You can check and edit this route from [Designer](https://designer.altogic.com/) like below.

![Change REDIRECT URL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pso888xvd0vx2fyvgpig.png)

Here in **getServerSideProps**, we check the query string parameters and according to each action, we perform some actions. Here is an **important** part!

`getAuthGrant()` function either takes a session token as a parameter **or** uses the one in the URL.

In the example below, **Altogic** sent the user an **email confirmation** mail. When clicked, it redirects to our specified **Redirect URL**, which is **auth-redirect**. 
There are three query parameters:

1. **status=200** indicates that Altogic managed to send me a valid token for my operation.
2. **access_token** gives us the token value I am going to use.
3. **action=email-confirm** indicates for which action I am going to use this token. In this case, it is confirming my email.

![Access token as query string parameter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cbvze4hqlmpi4ktowi18.png)

Here, we run this code **only on the server-side**, so we must **give** the session token as the parameter.

{% embed https://gist.github.com/myerekapan/024507efee2dc91ac818b877b0153acc %}

### Sign in functionality with Altogic

Altogic Client Library also has a built-in function for signing in users. You can check about it more [here](https://clientapi.altogic.com/v1.2.2/classes/AuthManager.html#signInWithEmail). The code snippet handles the form input using the **signInWithEmail** function.

**altogic**.auth.**signInWithEmail** takes two inputs:

1. **email** (**mandatory**)
2. **password** (**mandatory**)

{% embed https://gist.github.com/myerekapan/64596e2dca9be85f65ba6db7fa46116f %}

As you can see in the code above, we are sending a **POST** request to **/api/login** route. We are doing this to set the cookie for **server-side rendering** (SSR). If you are not going to use **SSR**, you can delete these lines.

### Why do we need cookies for SSR?
One of the key features of Next.js is **server-side rendering**. Meaning that some of the code will run **only** on the server and **not** on the client side. But session and user information is stored on the **client-side**. How do we understand if **we have a user authenticated** when a request is made to the server? For this purpose, we need to **set a cookie** on the server-side when we sign in and **delete it** when we sign out. This way, we can check if the user is authenticated on the server-side and then perform the actions we want.
Here is the code you need to add to your **api/login** folder:
{% embed https://gist.github.com/myerekapan/5a0b96a3e345b82d268ff013031ac450 %}
On any page, we can check if there is a user signed in or not. This part is needed both for route protection and fetching data special to the user with SSR.

Our sign-in screen should look like this:


![Sign-in Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tall7kmugko5ur2bysdc.png)

### How to check if there is a user authenticated via SSR?

**getServerSideProps** function runs every time the user makes a request. It runs **only** on the server, and its content is not exposed to the client. We check if a user is authenticated and redirect them to their profile or sign-in page accordingly.

{% embed https://gist.github.com/myerekapan/8afbc3bb4a664388f8e5c72254d13662 %}

### Signout users

Here is the page you can redirect your users to log them out. It simply invalidates the session, clears the context, and sends a **POST** request to **our-domain/api/logout** to clear the cookies.

{% embed https://gist.github.com/myerekapan/eb24edb5fcf5b1d0e4d61f057e1f889b %}

When we sign out, we need to **delete** the cookie we set on the **server-side** because the token value in the cookie is **no longer valid**.
Here is the code you need to add to your **api/logout** file:

{% embed https://gist.github.com/myerekapan/e6c6b59163a2f8a9ec13f31bf492b502 %}

### Storing user information in context

The `UserContext` creates a context and sets the user and session property null by default. To learn more about context and how to effectively use them, read [React’s documentation on context](https://reactjs.org/docs/context.html).

{% embed https://gist.github.com/myerekapan/6a887f0aa398eda548d006f1ab863460 %}

### More features
Our example application covers more features like uploading a profile picture, managing sessions, password recovery, password change, and email change. You can check all of them in the repository. Here, I just want to show you how easily you can implement them with client library functions.

{% embed https://gist.github.com/myerekapan/aa28da2f1500155711946159946cffe4 %}

## Conclusion
In this article, we built a simple yet capable email authentication app using **Next.js** and **Altogic Client Library**. Generally, building authentication is one of the most challenging parts of app development. Thanks to **Altogic**, we can build this functionality with just a few lines of code.
You can check out the [GitHub repository](https://github.com/altogic/altogic/tree/main/examples/nextjs-email-authentication) for other functionalities and the rest of the code. You can also clone it and build your app on top of it.