How to add Salesforce authentication to a Next.js application
Tags: appwrite, nextjs, salesforce, authentication
Published: 2022-08-02 08:09:00

Authentication is the process of verifying a user's identity before granting them access to your application. Authentication is important in policing users' access to different pages and resources. 

## What we will be building

This article discusses authenticating, collecting, and displaying a piece of user information with Appwrite’s Salesforce provider.

**GitHub URL** 

https://github.com/Iheanacho-ai/salesforce-auth-nextjs

## Prerequisites

To get the most out of this project, the following are required:

- A basic understanding of CSS, JavaScript, and React.js.
- Docker Desktop installed on your machine; run the `docker -v` command to verify that we have Docker Desktop installed. If not, install it from the [Get Docker documentation](https://docs.docker.com/get-docker/). 
- An Appwrite instance running on your computer. Check out [this article](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba) to create a local Appwrite instance; we will use Appwrite’s OAuth2 Salesforce provider to handle authenticating users in our application.
- A Salesforce developer account, [create a free account](https://developer.salesforce.com/signup) if you do not have one.


## Setting up our Next.js app

[Next.js](https://nextjs.org/) is an open-source React framework that enables us to build server-side rendered static web applications.

To create our Next.js app, navigate to thevpreferred directory and run the terminal command below: 

```bash
    npx create-next-app@latest
    # or
    yarn create next-app
```

After creating our app, we’ll change the directory to the project and start a development server with:

```bash
    cd <name of our project>
    npm run dev
```

To see our app, we go to [http://localhost:3000](http://localhost:3000).


## Installing Appwrite

[Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog&utm_campaign=salesforce_authentication_next) is an open-source, end-to-end, back-end server solution that allows developers to build applications faster. 

To use Appwrite in our Next.js application, we install the Appwrite client-side SDK for web applications.

```bash
    npm install appwrite
```
## Creating a new Appwrite project

During the creation of the Appwrite instance, we specified what hostname and port we would see our console in. The default value is [localhost:80](http://localhost/).

Go to [localhost:80](http://localhost/) and create a new account to see the console.

On our console, there is a **Create Project** button. Click on it to start a new project.

![Appwrite console](https://paper-attachments.dropbox.com/s_314B50E78D2533608F0DEE9BE97FEF3C5B7916B2F8CAC55559F4DCA3A07D86F6_1648400276700_Screenshot+64.png)



Our project dashboard appears once we have created the project. At the top of the page, there is a **Settings** bar. Click the **Settings bar** to access the **Project ID** and **API Endpoint**.  


![Appwrite console settings](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656159058446_Screenshot+433-2.png)


Now, copy the **Project ID** and **API Endpoint**, which we need to initialize the Appwrite Web SDK.


![Appwrite Console Settings](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656105010317_Screenshot+435.png)


Next, create an `init.js` file in our project's root directory to initialize the Appwrite Web SDK.

```js
    import { Appwrite } from 'appwrite';
    export const sdk = new Appwrite();
    sdk
      .setEndpoint('http://localhost/v1') // Replace this with your endpoint
      .setProject('projectID'); // Replace this with your ProjectID
```    

## Enabling the Salesforce provider in our application

In the Appwrite web [Console](http://localhost/console), click on **Users** on the left side of the dashboard to set up the Salesforce OAuth2 provider for our application.


![Appwrite Console Users](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656105142242_Screenshot+434.png)


Then, go to the **Settings** tab to see the OAuth2 providers supported by Appwrite.

![Appwrite Console Users Settings](https://paper-attachments.dropbox.com/s_98E598E82DA6A0EFE02589BF150D54DF5482BFE1594F1B46A5EA7C4854923304_1653479038602_Screenshot+341.png)



![Appwrite Console Users Settings](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656105292711_Screenshot+436.png)


In our Appwrite console, toggle the Salesforce provider to open the **Salesforce OAuth2 settings.**


![Appwrite Salesforce OAuth2 Setting](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656158958698_Screenshot+436-2.png)

![Appwrite Salesforce OAuth2 Setting](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656105317670_Screenshot+438.png)


Next, copy the **OAuth2 redirect URL**, as we’ll need it on the Salesforce dashboard.

**Creating an application on the Salesforce dashboard**

To use Appwrite’s Salesforce provider, we need to create an application on the Salesforce dashboard. Check out the [Salesforce documentation](https://help.salesforce.com/s/articleView?id=sf.connected_app_create_basics.htm&type=5) to understand how to create a Salesforce application. 

It is important to use the **OAuth2 redirect URI** as the **Callback URL** when filling out the information for the Salesforce application.

After creating the Salesforce application, click on the **Manage Consumer Details** to reveal your **Consumer Key** and **Consumer Secret**; we’ll need them in our Appwrite console.

![Salesforce Settings Dashboard](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656156956388_Screenshot+444.png)


Fill out the **App ID** and **App Secret** input field with the **Customer Key** and **Customer Secret** from the Salesforce dashboard, respectively. 

![Appwrite Salesforce OAuth Settings](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656158820030_Screenshot+439.png)



## Authenticating users in our application

Our application will contain two pages. The first page will authenticate and log in a user using the Appwrite Salesforce OAuth2 provider, and the second page will display the user details.

**Creating our login page**
We create our login page in our `index.jsx` file. The login page will consist of a button to allow users to log in to our application via Salesforce.

```jsx
    import styles from '../styles/Home.module.css'
    const Home = () => {
      return (
        <div className={styles.container}>
          <div class="login">
            <p>Click on this button to login</p>
            <button className= "button">Login with Salesforce</button>
          </div>
        </div>
      )
    }
    export default Home;
```
In our `global.css` file, we add the styling for our login page.

```css
.login{
  width: 450px;
  height: 200px;
  background: #fff;
  box-shadow: 0 10px 30px rgba(0,0,0,0.1);
  border-radius: 7px;
  margin: 10% auto;
  text-align: center;
  padding: 30px;
}

.button{
  width: 200px;
  height: 40px;
  background-color: #111;
  color: #fff;
  border-radius: 30px;
}
```
Here is how our login page looks.

![Login Page Salesforce](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656104297560_Screenshot+336.png)


**Creating the user profile page**
In the `pages` folder, create a `dashboard.jsx` to display the currently logged-in user profile.

```jsx
    const Dashboard = () => {
        return (
            <div className="user-details">
            <p><span>Name:</span></p>
            <p><span>Email: </span></p>
            <button className= "button">LogOut with Salesforce</button>
          </div>
        )
    }
    export default Dashboard;
```
Next, we add the styling for the dashboard in our `global.css` file.

```css
.login, .user-details{
  width: 450px;
  height: 200px;
  background: #fff;
  box-shadow: 0 10px 30px rgba(0,0,0,0.1);
  border-radius: 7px;
  margin: 10% auto;
  text-align: center;
  padding: 30px;
}

.button{
  width: 200px;
  height: 40px;
  background-color: #111;
  color: #fff;
  border-radius: 30px;
}

span{
  font-weight: 600;  
}
```
To see the user profile page, go to http://localhost:3000/dashboard.

![Appwrite Salesforce Dashboard](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656104321975_Screenshot+337.png)


**Authenticating a user with Appwrite's Salesforce provider**

In the `index.jsx` file, import the `sdk` instance into our file.

```jsx
    import { sdk } from '../init' 
```
Next, create a `loginWithSalesforce` function to authenticate and log a user into our application.

```jsx
    import { sdk } from '../init' 
    import styles from '../styles/Home.module.css'
    
    const Home = () => {
      const loginWithSalesforce = async() => {
        try {
          await sdk.account.createOAuth2Session('Salesforce', 'http://localhost:3000/dashboard', 'http://localhost:3000/error')
        } catch (error) {
          console.log(error)
        }
      }
      return (
        <div className={styles.container}>
          <div class="login">
            <p>Click on this button to login</p>
            <button className= "button">Login with Salesforce</button>
          </div>
        </div>
      )
    }
    export default Home;
```

The `loginWithSalesforce` function creates a user session with the Appwrite’s  `createOAuth2Session` function. This `createOAuth2Session` method receives three parameters:

- The OAuth2 provider we want to sign in a user with, which, in this example, is Salesforce
- The success argument is a redirect URL back to our app when the login is complete
- The failure argument is a redirect URL when the login fails

Next, we’ll pass the `loginWithSalesforce` method to the `onClick` event listener on the **Login with Salesforce** button.

```jsx
    <button className= "button" onClick={loginWithSalesforce}>Login with Salesforce</button>
```

**Displaying the stored user in our application**

Now, write the code below in the `dashboard.jsx` file to display the user currently logged in to our application.

```jsx
    import { useEffect, useState } from "react";
    import { useRouter } from "next/router";
    import { sdk } from "../init";
    
    const Dashboard = () => {
        const router = useRouter();
        const [name, setName] = useState();
        const [email, setEmail] = useState();
    
        const getUserSession = async () => {
            let response = await sdk.account.get()
            try {
                if(response) {
                    setName(response.name);
                    setEmail(response.email)
                }
            } catch (error) {
                console.log(error)
            }
        }
    
        const logOutWithSalesforce = async () => {
            try {
                await sdk.account.deleteSession('current')
                alert('logout successful') 
                router.push('/');
            } catch (error) {
                console.log(error)  
            }
        }
    
        useEffect(() => {
            getUserSession()
        }, [])
    
        return (
            <div className="user-details">
            <p><span>Name:</span></p>
            <p><span>Email: </span></p>
            <button className= "button">LogOut with Salesforce</button>
          </div>
        )
    }
    export default Dashboard;
```
In the code block above, we did the following:

- Created `name` and `email` state variables to hold a user's information.
- Created a `getUserSession` function to fetch the currently logged in user information. This `getUserSession` function updates the `name` and `email` variables.
- Used the `useEffect` lifecycle hook to run the `getUserSession` function when the application mounts.
- Create a `logOutWithSalesforce` function that logs a user out of our application using the Appwrite `deleteSession` method. This `logOutWithSalesforce` function then navigates to our application's home page using the Next.js `useRouter` hook.
- Logs any error encountered during user logout.

Next, we’ll render the contents of the `name` and `email` variables on our user profile page. We then pass the `logOutWithSalesforce` function to the `onClick` event listener on the **logOutWithSalesforce** button.

```jsx
    <div className="user-details">
        <p><span>Name:</span>{name}</p>
        <p><span>Email: </span>{email}</p>
        <button className= "button" onClick={logOutWithSalesforce}>LogOut with Salesforce</button>
    </div>
```
Here is how our application looks now.


![Login Page](https://paper-attachments.dropbox.com/s_A45735D49A4D722B717ECC48F8EEB7053659377191B4874AA0993069143F6AC2_1656107983199_giphy-2.gif)



## Conclusion

This article discussed using Appwrite's Salesforce OAuth2 provider to authenticate a user. 

## Resources

Here are some resources that might be helpful.

- [Create a local Appwrite instance in 3 steps](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba)
- [Create Salesforce applications](https://www.tutorialkart.com/salesforce/how-to-create-an-app-in-salesforce/)
- [Account API](https://appwrite.io/docs/client/account?sdk=web-default#accountCreateOAuth2Session?utm_source=hackmamba&utm_medium=blog&utm_campaign=salesforce_authentication_next)