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*']
}
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']
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);
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;
}
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'
)
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*']
}
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.
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
We see that there is no cors warning, so it's ok
Let's try another site
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)
}
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)
}
The Article : Create A Middleware In NextJS 13
Top comments (0)