Open In App

Next JS Middleware: Extending Functionality in Your Application

Middleware plays an important role in creating backend applications which are used to intercept incoming requests, perform actions, and modify responses before send to routing handlers. In this article, we will understand middleware in Next.js by creating an authentication middleware.

Prerequisites:

What are Middlewares?

Middleware is a piece of code that redefines the functionality of your written logic. It enhances the logic and provides an additional capability. It has access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. Middleware modifies a request before it reaches the destination. It is very helpful in performing tasks like authentication and data manipulation.



Syntax:

// Define your middleware function
const myMiddleware = (req: Request, res: Response, next: NextFunction) => {
// Middleware logic
console.log('Middleware executed');
// Call the next middleware function in the stack
next();
};

Functioning of a Middleware

Example: In this example, We will secure the profile page within an authentication middleware with the help of a higher-order component (HOC) to envelop the profile page component. This higher-order component will interfere with the request to the profile page, ensuring that only users with valid credentials can access it.

Steps to Create a Next.js app

Step 1: Create a Next.js app by using the command provided below.



npx create-next-app next-middleware

Enter into the app directory created.

cd next-middleware

Step 2: Create the required files and folders as suggested in file structure.

File Structure:

file structure

The updated dependencies in package.json file will look like:

"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.1.0"
},
"devDependencies": {
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0"
}

Example: Add the following codes in the respective files.




//authMiddleware.js
 
import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
 
const authMiddleware = (WrappedComponent) => {
    const AuthComponent = (props) => {
        const router = useRouter();
        const [isAuthenticated, setIsAuthenticated] = useState(false);
 
        useEffect(() => {
            // Check for your authentication criteria here
            const username = localStorage.getItem("username");
            const password = localStorage.getItem("password");
 
            if (username === "geeksforgeeks" && password === "1234") {
                setIsAuthenticated(true);
            } else {
                router.replace("/login");
            }
        }, []);
 
        if (isAuthenticated) {
            return <WrappedComponent {...props} />;
        } else {
            return null;
        }
    };
 
    return AuthComponent;
};
 
export default authMiddleware;




//Profile.js
 
import React from 'react'
import authMiddleware from '../middlewares/authMiddleware'
 
const profile = () => {
    return (
        <div className='max-w-sm mx-auto mt-12
                        text-3xl bg-blue-400 text-white
                        shadow-3xl rounded-xl border p-10'>
            <h1>
                Hi I am the User, and I am Logged In
            </h1>
        </div>
    )
}
 
export default authMiddleware(profile)




//Login.js
 
import { useState } from "react";
import { useRouter } from "next/router";
 
const Login = () => {
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const router = useRouter();
 
    const handleLogin = () => {
        // Check the username and password and perform login logic
        localStorage.setItem("username", username);
        localStorage.setItem("password", password);
        // Redirect to the profile page
        router.push("/profile");
    };
 
    const handleKeyPress = (e) => {
        if (e.key === "Enter") {
            handleLogin();
        }
    };
 
    return (
        <div className="flex flex-col max-w-sm mt-12 space-y-3 mx-auto">
            <h1 className="text-gray-600 text-2xl">Login</h1>
            <input
                className="border p-2"
                placeholder="Enter username"
                value={username}
                onChange={(e) => setUsername(e.target.value)}
                onKeyPress={handleKeyPress}
            />
            <input
                className="border p-2"
                placeholder="Enter password"
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                onKeyPress={handleKeyPress}
            />
            <button
                onClick={handleLogin}
                className="border p-2 focus:bg-white focus:text-gray-400
                    focus:border bg-sky-600 text-white"
            >
                Submit
            </button>
        </div>
    );
};
 
export default Login;

Step 3: To start the application run the following codes.

npm run dev

Output:


Article Tags :