DEV Community

Cover image for Create A Middleware In NextJS 13
Hòa Nguyễn Coder
Hòa Nguyễn Coder

Posted on

Create A Middleware In NextJS 13

Now I will implement an important function in Next.js. That is we need to handle Middleware, so what is middleware for? We can understand as follows:

Middleware is used to handle problems. When a request needs to run into our software, it needs to go through this Middleware first. What's the point of going through it first? Let's go through it to check if the user information is valid or not, check such as: origin , cookie , pathname , hostname , header , ..... that we allow access to the routers in the application . Depending on the application we install, please check

If you have worked on Middleware in Laravel, or React, then you can imagine, it's the same.

Example:
Laravel: then we need to create Middleware to check the user's Authentication or check Role , Group , Permissions ,...

React: we often use middleware in the libraries _Redux , Redux-Toolkit , Redux-Saga _,...

NextJS : I create a Middleware file at the same level as app, pages , or inside src . It will check every route passing through the application

Okay, first I will create a middleware.ts file at the same level as the app folder



import { NextRequest, NextResponse } from "next/server";
const allow_origin_lists :string[]   = process.env.NODE_ENV==='production'?['https://hoanguyenit.com','https://100daysofcode.hoanguyenit.com']:
['https://www.google.com','http://localhost:3000']
export default function middleware(request: NextRequest){
    console.log("env",process.env.NODE_ENV);
    console.log("Host",request.headers.get('host'))
    console.log("Origin",request.headers.get('origin'));
    console.log("Url",request.url)
    console.log("Mehod:",request.method);

    //Chúng ta kiểm tra các request tại đây
    const origin: string | null  = request.headers.get('origin')
    const res = NextResponse.next()
    const res_404 = new NextResponse(null,
        {
            status: 404,
            statusText:"Bad request",
            headers:{
                'Content-Type':'text/plain'
            }
        })

    console.log(allow_origin_lists);
    if(origin && !allow_origin_lists.includes(origin)){
        return res_404;
    }

    // add the CORS headers to the response
    res.headers.append('Access-Control-Allow-Credentials', "true")
    res.headers.append('Access-Control-Allow-Origin', origin) 
    res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT')
    res.headers.append(
        'Access-Control-Allow-Headers',
        'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
    )

    return res;
}
export const config = {
    matcher:[ '/api/:path*']
  }


Enter fullscreen mode Exit fullscreen mode

If you look at the code above, I use it to check the origins that allow access to the application



const allow_origin_lists :string[]   = process.env.NODE_ENV==='production'?['https://100daysofcode.hoanguyenit.com']:
['https://www.google.com','http://localhost:3000']


Enter fullscreen mode Exit fullscreen mode

Besides, in function middleware we can check parameter values ​​such as *method *, *origin *, *url *, *host *. These values ​​are essential when we authenticate where user requests come from, what website, and what methods are allowed



console.log("env",process.env.NODE_ENV);
   console.log("Host",request.headers.get('host'))
   console.log("Origin",request.headers.get('origin'));
   console.log("Url",request.url)
   console.log("Mehod:",request.method);


Enter fullscreen mode Exit fullscreen mode

Next we can check whether origin is in the origin array we allow or not. If not, the response will be 404



 const res_404 = new NextResponse(null,
        {
            status: 404,
            statusText:"Bad request",
            headers:{
                'Content-Type':'text/plain'
            }
        })

if(origin && !allow_origin_lists.includes(origin)){
        return res_404;
    }


Enter fullscreen mode Exit fullscreen mode

The following paragraph is also easy to use:
Access-Control-Allow-Credentials : allows the browser to send CORS requests with authentication information (like a cookie or another credential)

Access-Control-Allow-Origin : defines the origin to which the browser is allowed to send CORS requests

Access-Control-Allow-Methods : defines the HTTP methods that the server accepts from browsers sending CORS requests

Access-Control-Allow-Headers : defines optional HTTP headers that the browser can include in CORS *requests. This is important if you want to allow the browser to send other custom headers. In this case, a list of headers is listed, including *X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X- API-Version



res.headers.append('Access-Control-Allow-Credentials', "true")
    res.headers.append('Access-Control-Allow-Origin', origin) 
    res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT')
    res.headers.append(
        'Access-Control-Allow-Headers',
        'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
    )


Enter fullscreen mode Exit fullscreen mode

Next we can provide some routes to let the Middleware know how to check our important routes, we can customize it, as desired.



export const config = {
    matcher:[ '/api/:path*']
  }


Enter fullscreen mode Exit fullscreen mode

The matcher config above, if you do not also provide Middleware, it will by default scan the entire application route, you can see the image here.

Create A Middleware In NextJS 13 - hoanguyenit.com
If you tell the Middleware which routes to check, it will only check those routes.

For example, I only provide middleware checks in the** /api/:path* **route . Then it only checks at that link

Create A Middleware In NextJS 13 - hoanguyenit.com
Okay, now let's check it out

Create A Middleware In NextJS 13 - hoanguyenit.com
We see that there is no cors warning, so it's ok

Let's try another site

Create A Middleware In NextJS 13 - hoanguyenit.com
Getting a Cors error because our application is in development state , not yet available ( production )

There are many things you can check, such as checking whether you are using the phone or not



import { NextResponse, userAgent } from 'next/server'
......
 const { device } = userAgent(request)
if (host=== 'hoanguyenit.com' && device.type === 'mobile') {
    const url = request.nextUrl.clone()
   //cập nhật lại host name
    url.hostname = 'm.hoanguyenit.com'
  // chuyển hướng nó
    return NextResponse.redirect(url)
  }


Enter fullscreen mode Exit fullscreen mode

Or for example, check the pathname*_ "/api/post/12"_* changes to /api/post/99



if (request.nextUrl.pathname === 'api/post/12')
    const url = request.nextUrl.clone()
    url.pathname = '/api/post/99'
    return NextResponse.redirect(url)
  }


Enter fullscreen mode Exit fullscreen mode

The Article : Create A Middleware In NextJS 13

Top comments (0)