Part 118: Implementing Authentication in Next.js: A Step-by-Step Guide
[App] Authentication Overview

In today's digital landscape, securing user interactions is paramount. If you're building a web application with Next.js and want to ensure only authenticated users can engage with certain features, such as posting comments, then this guide is for you. We'll walk through setting up a basic authentication system that restricts comment posting to logged-in users. Let's dive in!
Setting the Stage
Before we start, ensure you have your Next.js development server running. Additionally, if you're using a headless CMS like Strapi to fetch content, that server should be up and running too. Previously, we added a feature allowing users to post comments on reviews. Currently, anyone can post a comment without authentication, which opens the door to spam. Our goal is to restrict this capability to authenticated users.
Adding a Sign-In Page
Step 1: Create the Route
First, we'll create a new route for the sign-in page. You can duplicate an existing page, like the "about" page, and rename it to "sign-in".
Step 2: Implement the Sign-In Page
This page will display a form where users can enter their credentials (email and password). Here's a basic setup for the SignInPage:
// File path: app/sign-in/page.jsx
import Heading from '@/components/Heading';
import SignInForm from '@/components/SignInForm';
export const metadata = {
title: 'Sign In',
};
export default function SignInPage() {
return (
<>
<Heading>Sign In</Heading>
<SignInForm />
</>
);
}Step 3: Create the Sign-In Form
We'll use an existing component, CommentForm, as a starting point. Duplicate it and rename it to SignInForm. Update the fields to accept "email" and "password".
// File path: components/SignInForm.jsx
'use client';
import { signInAction } from '@/app/sign-in/actions';
import { useFormState } from '@/lib/hooks';
export default function SignInForm() {
const [state, handleSubmit] = useFormState(signInAction);
return (
<form onSubmit={handleSubmit} className="border bg-white flex flex-col gap-2 max-w-screen-sm mt-3 px-3 py-3 rounded">
<div className="flex">
<label htmlFor="emailField" className="shrink-0 w-32">
Email
</label>
<input id="emailField" name="email" type="email" className="border px-2 py-1 rounded w-full" />
</div>
<div className="flex">
<label htmlFor="passwordField" className="shrink-0 w-32">
Password
</label>
<input id="passwordField" name="password" type="password" className="border px-2 py-1 rounded w-full" />
</div>
{Boolean(state.error) && (
<p className="text-red-700">{state.error.message}</p>
)}
<button type="submit" disabled={state.loading} className="bg-orange-800 rounded px-2 py-1 self-center text-slate-50 w-32 hover:bg-orange-700 disabled:bg-slate-500 disabled:cursor-not-allowed">
Submit
</button>
</form>
);
}Step 4: Set Up the Sign-In Action
Create a new action file to handle form submissions. For now, we'll simply log the form data to the console.
// File path: app/sign-in/actions.js
'use server';
export async function signInAction(formData) {
console.log('[signInAction]', formData);
}Connecting the Sign-In Page
Modify your navigation bar to include a "Sign In" link that directs users to the new page.
// File path: components/NavBar.jsx
export default function NavBar() {
return (
<nav>
<ul>
<li>
<NavLink href="/sign-in">
Sign in
</NavLink>
</li>
{/* Other links */}
</ul>
</nav>
);
}Testing the Setup
Navigate to the "Sign In" page, enter your email and password, and submit the form. Check your server logs to ensure the form data is being logged correctly. This confirms that our form is functioning as expected.
Next Steps
With the basic form in place, our next task is to implement logic within the signInAction to authenticate users. This involves verifying the email and password against stored credentials. We'll explore this in the next part of our series.
By following these steps, you've laid the groundwork for a secure authentication system in your Next.js application. Stay tuned for further enhancements as we delve deeper into user authentication and authorization.
Last updated