• Homeright=arrow
  • Blogright=arrow
  • A Complete Guide to Exploring Authentication in Next.js
featureImage

A Complete Guide to Exploring Authentication in Next.js

Authentication is the process of verifying the identity of a user, system, or entity attempting to access a particular resource or service. It is a crucial aspect of web development to ensure that only authorized users can access protected information, perform specific actions, or interact with certain functionalities within an application. The primary goal of authentication is to confirm the legitimacy of the entity seeking access by validating the provided credentials.

Authentication Techniques:

Authentication techniques are the methods and processes used to validate the identities of persons or systems seeking to access a certain resource. There are several authentication mechanisms available in web development, each with its own set of strengths, use cases, and considerations. Here are a few typical authentication methods:

  1. Username and Password Authentication: Users provide a unique username and a secret password associated with their account.
  2. Token-Based Authentication: Users receive a token (e.g., JSON Web Token or JWT) upon successful authentication, which is then sent with each subsequent request.
  3. OAuth (Open Authorization): Allows users to log in using existing credentials from a third-party provider (e.g., Google, Facebook) without sharing their password.
  4. Session-Based Authentication: Stores user data on the server and maintains a session identifier on the client side (usually in a cookie).
  5. JWT (JSON Web Token) Authentication: Encodes user information into a token, which is then passed between the client and server.

Choosing an authentication approach should be based on your application's unique needs, user interface concerns, and security goals.

Adding Authentication

Authentication in a Next.js application may be implemented in a variety of ways, depending on your needs and preferences. One typical way is to utilize a third-party authentication service, such as Auth0 or Firebase, or to create custom authentication using libraries like NextAuth.js and a backend server.

Here's a basic example of NextAuth.js with a custom backend. This example requires that you have a basic grasp of Next.js and Node.JS.

First, Install NextAuth.js and other required packages:

npm install next-auth react-hook-form

Now, Create a login form component, for example, components/LoginForm.js:

	// components/LoginForm.js
import { useState } from 'react';
import { useForm } from 'react-hook-form';

const LoginForm = ({ onSubmit }) => {
const { register, handleSubmit, formState: { errors } } = useForm();

return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="username">Username</label>
<input type="text" id="username" {...register('username', { required: true })} />
{errors.username && <span>This field is required</span>}
</div>
<div>
<label htmlFor="password">Password</label>
<input type="password" id="password" {...register('password', { required: true })} />
{errors.password && <span>This field is required</span>}
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
);
};
export default LoginForm;

After that, we have to create an API Route for Authentication. Create a file in your app/api/auth/[...nextauth]/route.js directory:


import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
providers: [
Providers.Credentials({
// The name to display on the sign-in form (e.g., 'Sign in with...')
name: 'Credentials',
credentials: {
username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" }
},
authorize: async (credentials) => {
// Add your custom authentication logic here
const user = { id: 1, name: 'John Doe', email: 'john@example.com' };

if (user) {
return Promise.resolve(user);
} else {
return Promise.resolve(null);
}
}
})
// Add other providers as needed
],
session: {
jwt: true,
},
callbacks: {
async jwt(token, user) {
if (user) {
token.id = user.id;
}
return token;
},
async session(session, token) {
session.user = token;
return session;
}
}
});

Then, Create a login page (app / login /page.jsx) that uses the custom login form:

// pages/login.js
import { signIn } from 'next-auth/react';
import LoginForm from '@/components/LoginForm';

const LoginPage = () => {
const handleLogin = async (data) => {
await signIn('credentials', {
username: data.username,
password: data.password,
redirect: false, // Do not automatically redirect on success
});

// Redirect manually if needed
// router.push('/dashboard');
};

return (
<div>
<h1>Login</h1>
<LoginForm onSubmit={handleLogin} />
</div>
);
};
export default LoginPage;

Next, we have to protect Routes with Authentication. To do this, we can use the getSession function provided by NextAuth.js. For example, in your (app/protected/page.jsx ) use the following code:

import { getSession } from 'next-auth/react';

function ProtectedPage({ user }) {
return (
<div>
<h1>Protected Page</h1>
<p>Welcome, {user.name}!</p>
</div>
);
}

export async function getServerSideProps(context) {
const session = await getSession(context);

if (!session) {
return {
redirect: {
destination: '/login',
permanent: false,
},
};
}

return {
props: {
user: session.user,
},
};
}
export default ProtectedPage;

Finally,  add Authentication to Your Pages by importing the useSession hook from NextAuth.js:

// pages/index.js
import { useSession } from 'next-auth/react';

function HomePage() {
const { data: session } = useSession();

return (
<div>
{session ? (
<p>Welcome, {session.user.name}!</p>
) : (
<p>Please sign in</p>
)}
</div>
);
}
export default HomePage;

Conclusion

Congratulations! You have successfully added a simple authentication method to the next.js. Depending on your needs, you should enhance security, be well-optimized, add error handling, and possibly integrate with external authentication providers. For any help, please get in touch with us. Our dedicated team will help you at every step of your journey.

footer-particlefooter-particlefooter-particlefooter-particlefooter-particle
back-to-top