How to add Salesforce authentication to a Next.js application

Amarachi Iheanacho - Aug 2 '22 - - Dev Community

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.
  • An Appwrite instance running on your computer. Check out this article 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 if you do not have one.

Setting up our Next.js app

Next.js 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:

    npx create-next-app@latest
    # or
    yarn create next-app
Enter fullscreen mode Exit fullscreen mode

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

    cd <name of our project>
    npm run dev
Enter fullscreen mode Exit fullscreen mode

To see our app, we go to http://localhost:3000.

Installing Appwrite

Appwrite 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.

    npm install appwrite
Enter fullscreen mode Exit fullscreen mode

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.

Go to localhost:80 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

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

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

Appwrite Console Settings

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

    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
Enter fullscreen mode Exit fullscreen mode

Enabling the Salesforce provider in our application

In the Appwrite web Console, click on Users on the left side of the dashboard to set up the Salesforce OAuth2 provider for our application.

Appwrite Console Users

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

Appwrite Console Users Settings

Appwrite Console Users Settings

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

Appwrite Salesforce OAuth2 Setting

Appwrite Salesforce OAuth2 Setting

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 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

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

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.

    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;
Enter fullscreen mode Exit fullscreen mode

In our global.css file, we add the styling for our login page.

.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;
}
Enter fullscreen mode Exit fullscreen mode

Here is how our login page looks.

Login Page Salesforce

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

    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;
Enter fullscreen mode Exit fullscreen mode

Next, we add the styling for the dashboard in our global.css file.

.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;  
}
Enter fullscreen mode Exit fullscreen mode

To see the user profile page, go to http://localhost:3000/dashboard.

Appwrite Salesforce Dashboard

Authenticating a user with Appwrite's Salesforce provider

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

    import { sdk } from '../init' 
Enter fullscreen mode Exit fullscreen mode

Next, create a loginWithSalesforce function to authenticate and log a user into our application.

    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;
Enter fullscreen mode Exit fullscreen mode

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.

    <button className= "button" onClick={loginWithSalesforce}>Login with Salesforce</button>
Enter fullscreen mode Exit fullscreen mode

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.

    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;
Enter fullscreen mode Exit fullscreen mode

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.

    <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>
Enter fullscreen mode Exit fullscreen mode

Here is how our application looks now.

Login Page

Conclusion

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

Resources

Here are some resources that might be helpful.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .