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
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
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
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.
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.
Now, copy the Project ID and API Endpoint, which we need to initialize the Appwrite Web SDK.
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
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.
Then, go to the Settings tab to see the OAuth2 providers supported by Appwrite.
In our Appwrite console, toggle the Salesforce provider to open the Salesforce OAuth2 settings.
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.
Fill out the App ID and App Secret input field with the Customer Key and Customer Secret from the Salesforce dashboard, respectively.
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;
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;
}
Here is how our login page looks.
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;
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;
}
To see the user profile page, go to http://localhost:3000/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'
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;
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>
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;
In the code block above, we did the following:
- Created
name
andemail
state variables to hold a user's information. - Created a
getUserSession
function to fetch the currently logged in user information. ThisgetUserSession
function updates thename
andemail
variables. - Used the
useEffect
lifecycle hook to run thegetUserSession
function when the application mounts. - Create a
logOutWithSalesforce
function that logs a user out of our application using the AppwritedeleteSession
method. ThislogOutWithSalesforce
function then navigates to our application's home page using the Next.jsuseRouter
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>
Here is how our application looks now.
Conclusion
This article discussed using Appwrite's Salesforce OAuth2 provider to authenticate a user.
Resources
Here are some resources that might be helpful.