app.use() alternative in Next Js
Answered
Parson Russell Terrier posted this in #help-forum
Parson Russell TerrierOP
hello everyone i want to use app.use(helmet()) middleware in my next js so how can i use it?? please help
Answered by joulev
you can't use helmet()* in nextjs, but to return http headers, you can use the
* unless you are willing to follow the custom server route https://nextjs.org/docs/pages/building-your-application/configuring/custom-server, in that case adding helmet directly is possible
headers() option in next.config.js https://nextjs.org/docs/app/api-reference/next-config-js/headers, or set the headers in middleware https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers* unless you are willing to follow the custom server route https://nextjs.org/docs/pages/building-your-application/configuring/custom-server, in that case adding helmet directly is possible
16 Replies
@Parson Russell Terrier hello everyone i want to use app.use(helmet()) middleware in my next js so how can i use it?? please help
you can't use helmet()* in nextjs, but to return http headers, you can use the
* unless you are willing to follow the custom server route https://nextjs.org/docs/pages/building-your-application/configuring/custom-server, in that case adding helmet directly is possible
headers() option in next.config.js https://nextjs.org/docs/app/api-reference/next-config-js/headers, or set the headers in middleware https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers* unless you are willing to follow the custom server route https://nextjs.org/docs/pages/building-your-application/configuring/custom-server, in that case adding helmet directly is possible
Answer
@joulev you can't use helmet()* in nextjs, but to return http headers, you can use the `headers()` option in next.config.js <https://nextjs.org/docs/app/api-reference/next-config-js/headers>, or set the headers in middleware <https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers>
\* unless you are willing to follow the custom server route <https://nextjs.org/docs/pages/building-your-application/configuring/custom-server>, in that case adding helmet directly is possible
Parson Russell TerrierOP
i have use that in middleware file by doing this
1. checking if this is api route /api
2. if yes than call those middleware functions
xssClean()
helmet()
1. checking if this is api route /api
2. if yes than call those middleware functions
xssClean()
helmet()
@joulev you can't use helmet()* in nextjs, but to return http headers, you can use the `headers()` option in next.config.js <https://nextjs.org/docs/app/api-reference/next-config-js/headers>, or set the headers in middleware <https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers>
\* unless you are willing to follow the custom server route <https://nextjs.org/docs/pages/building-your-application/configuring/custom-server>, in that case adding helmet directly is possible
Parson Russell TerrierOP
thank you, learned something new from this
helmet uses the res.setHeader syntax, which is not how middleware sets response header. it's probably silently failing
@joulev really? how did you do it?
Parson Russell TerrierOP
import { NextRequest, NextResponse } from "next/server";
import { jwtVerify } from "jose";
import { UserJWTPayload } from "./shared/types/JWT";
//@ts-ignore
import xssClean from "xss-clean";
import expressMongoSanitize from "express-mongo-sanitize";
export const getJwtSecretKey = () => {
const secret = process.env.JWT_SECRET_KEY;
if (!secret || secret.length === 0) {
throw new Error("env JWT_SECRET_KEY is not set.");
}
return secret;
};
const verifyJWTToken = async (token: string) => {
try {
const verified = await jwtVerify(
token,
new TextEncoder().encode(getJwtSecretKey())
);
return verified.payload as UserJWTPayload;
} catch (err) {
throw new Error("Your token has expired! please sign in");
}
};
export async function middleware(req: NextRequest) {
if (req.nextUrl.pathname.startsWith("/api")) {
xssClean();
expressMongoSanitize();
} else {
const token = req.cookies.get("token")?.value;
const verifyToken =
token &&
(await verifyJWTToken(token).catch((err) => {
console.log(err);
}));
// if user is not authenticared than allow him to got to login & register page
if (
(req.nextUrl.pathname.startsWith("/login") ||
req.nextUrl.pathname.startsWith("/register")) &&
!verifyToken
) {
return;
}
const url = req.url;
// if user is authenticated and he tries to navigate to /login and /register than redirect to home page
if ((url.includes("/login") || url.includes("/register")) && verifyToken) {
return NextResponse.redirect(new URL("/", url));
}
if (!verifyToken) {
return NextResponse.redirect(new URL("/login", url));
}
}
}
export const config = {
matcher: ["/", "/login", "/register", "/api/:path*"],
};@joulev yes, here xssClean() and expressMongoSanitize() do nothing
Parson Russell TerrierOP
🥲 why?
nextjs follows a different syntax from express, things using express syntax does not work in nextjs
Parson Russell TerrierOP
okay i thought this will work as this is similar to app.use
so how can i configure these 2 packages in my code correctly??
so how can i configure these 2 packages in my code correctly??
@Parson Russell Terrier okay i thought this will work as this is similar to app.use
so how can i configure these 2 packages in my code correctly??
for xss-clean and express-mongo-sanitize: you have to sanitise and validate user input manually in the api routes. can't do it in middleware.
about helmet(): build and send the http headers manually https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers
about helmet(): build and send the http headers manually https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers
@joulev for xss-clean and express-mongo-sanitize: you have to sanitise and validate user input manually in the api routes. can't do it in middleware.
about helmet(): build and send the http headers manually <https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers>
Parson Russell TerrierOP
okay understood, so in my case what will happen in those 2 lines??
@Parson Russell Terrier okay understood, so in my case what will happen in those 2 lines??
nothing.
in your case, these functions are simply declared and left as is. it is like this
the
xssClean() (and similar functions) returns a function (req, res, next) => { ... }. these functions only work in places where (req, res, next) => {...} is expected, e.g. inside express .use().in your case, these functions are simply declared and left as is. it is like this
function generateAdder() {
return function (a, b) {
return a + b;
};
}
function main() {
generateAdder();
}the
a + b part is never run, so the function does nothing.Parson Russell TerrierOP
is this correct way to sanitize the fields?? @joulev