Integrating Auth.js OAuth with Mongodb
October 6, 2024
In this tutorial, we’ll be combining the power of Auth.js and Google OAuth to enable seamless logins for your users, while securely storing their data in MongoDB 🛡️.
But wait—before we dive into the code, make sure you have these essential secret keys at the ready:
AUTH_GOOGLE_ID =
AUTH_GOOGLE_SECRET =
MONGODB_URI =
You can check this video on how to get the GOOGLE CLIENT ID
and GOOGLE CLIENT SECRET
, and kindly check this out too for the callback URI
Now we can get started
Installing Auth.js
Start by installing the appropriate package
Setup environment
The only environment variable that is mandatory is the AUTH_SECRET
. This is a random value used by the library to encrypt tokens and email verification hashes. (See Deployment to learn more). You can generate one via the official Auth.js CLI running:
This will also add it to your .env file, respecting the framework conventions (eg.: Next.js’ .env.local).
Configure
Next, create the Auth.js config file and object. This is where you can control the behaviour of the library and specify custom authentication logic, adapters, etc. We recommend all frameworks to create an auth.ts
file in the project. In this file we’ll pass in all the options to the framework specific initalization function and then export the route handler(s), signin and signout methods, and more.
-
Start by creating a new
auth.ts
file at the root of your app with the following content. -
Add a Route Handler under
/app/api/auth/[...nextauth]/route.ts
. -
Add optional Middleware to keep the session alive, this will update the session expiry every time its called.
Setup Auth.js provider
Let’s enable Google as a sign in option in our Auth.js configuration. You’ll have to import the Google provider from the package and pass it to the providers array we setup earlier in the Auth.js config file:
In Next.js we recommend setting up your configuration in a file in the root of your repository, like at auth.ts
.
Add the handlers
which NextAuth
returns to your api/auth/[...nextauth]/route.ts
file so that Auth.js can run on any incoming request.
Create button component to trigger Auth.js sign in when clicked.
Click the “Sign in with Google" button and if all went well, you should be redirected to Google and once authenticated, redirected back to the app!
Setup MongoDB
Install Mongoose
You need to install Mongoose in a Next.js project when working with MongoDB because Mongoose provides a powerful abstraction for interacting with MongoDB databases.
Creating MongoDB Connection
In the /lib/database/index.ts
file, we’ll set up the connection to MongoDB using Mongoose. This code ensures that our application reuses the same connection, which is especially important in serverless environments like Next.js to avoid performance issues.
- MONGODB_URI: This is the URI for your MongoDB database, which you’ll typically store in environment variables for security.
- Connection Caching: We are caching the connection (
cached.conn
) to ensure it’s reused across multiple requests, avoiding excessive connection overhead. - Database Name: In this case, we are using
folioart
as the database name, but you can change it to whatever fits your project.
Creating Model User
Next, we’ll define a User model using Mongoose. This will allow us to create, retrieve, and manipulate user data in the database.
- User Schema: We define the schema for our User model with fields like email, username, name, and photo.
- Unique Constraints: Both email and username are set to be unique, ensuring that no two users can share the same email or username.
Creating a New User
Now, we’ll create a function to handle the creation of a new user in our database. This function will check if the user already exists based on their email or username. If they don't exist, a new user is created.
- Connecting to MongoDB: We use the connectMongo function to ensure the connection is established.
- Checking for Existing User: Before creating a new user, we check if one already exists with the same email or username.
- Returning the New User: If the user is successfully created, we return the new user data.
Integrating Auth.js OAuth with MongoDB
Now that you have your MongoDB set up, let’s bring in authentication using NextAuth.js. Specifically, we’ll configure Google OAuth as the login provider and store the user data in MongoDB.
Set Up Google as an Authenticator Provider
Let’s start by configuring Google OAuth as the provider in Auth.js. This will enable your users to log in using their Google account credentials.
Update your auth.ts
- GoogleProvider: This sets up Google as the authentication provider. You need to provide the
GOOGLE_CLIENT_ID
andGOOGLE_CLIENT_SECRET
(which should be in your environment variables).
Handling User Login with Callbacks
Now, we’ll dive into callbacks. These functions handle what happens after a user signs in—like creating a user in MongoDB and adding user data to the session.
-
signIn Callback: This function runs when a user signs in using Google. It extracts user details (
id
,name
,email
,image
), creates a new user object, and saves it to MongoDB via thecreateUser
function.- If the user already exists, it won’t create a new user.
- The function returns true, allowing the login process to complete.
-
session Callback: This function adds the user’s data to the session object, making it available across your app.
Testing
Now that we’ve set up Auth.js with Google OAuth and configured MongoDB to store user data, let’s test the integration to ensure everything works as expected.
We’ll create a simple page that:
- Authenticates the user: If the user is signed in, it will display their session data.
- Handles Sign Out: It will allow the user to sign out using a simple button.
Create sign-out button
First we need to create sign-out button
Create a Homepage
For the homepage we only need to call SignIn Component that we created before
Create a Page for Testing
- We use the
auth()
function to retrieve the session object. - If the user is not authenticated, we simply show a message:
Not authenticated
. - If the user is authenticated, we display the session details using
JSON.stringify(session, null, 2)
to format the session data for readability.