middleware bug?
Answered
Elm sawfly posted this in #help-forum
Elm sawflyOP
UNABLE_TO_VERIFY_LEAF_SIGNATURE
how to get past this error, it only happens on a fetch in middleware but not anywhere else in the app. i tried everything, multiple different certificates from different services. reverseproxy etc im completely out of ideas.... why can i signin using endpoints on same api, create users etc but i cant make a fetch inside middleware. when i do it goes bonkers
how to get past this error, it only happens on a fetch in middleware but not anywhere else in the app. i tried everything, multiple different certificates from different services. reverseproxy etc im completely out of ideas.... why can i signin using endpoints on same api, create users etc but i cant make a fetch inside middleware. when i do it goes bonkers
Answered by Toyger
hmm, ok, if you have argo tunnel then it's not a viable option.
ideally you should have public ipv4, right now you only can serve site with CF ssl.
as possible workaround maybe you can try
https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites
and use some path on site that will proxy your cf proxied url.
it's kinda additional hops, but still viable workaround, it should terminate ssl with vercel so error should gone.
ideally you should have public ipv4, right now you only can serve site with CF ssl.
as possible workaround maybe you can try
https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites
and use some path on site that will proxy your cf proxied url.
it's kinda additional hops, but still viable workaround, it should terminate ssl with vercel so error should gone.
31 Replies
Elm sawflyOP
this only works in dev/nonsecure enviroment..
//Middleware
export async function middleware(req: NextRequest) {
const accessToken = req.cookies.get("accessToken")?.value;
const refreshToken = req.cookies.get("refreshToken")?.value;
if (!accessToken || isTokenExpired(accessToken as string)) {
if (refreshToken) {
try {
const response = await fetch(
`${process.env.EXTERNAL_API}/auth/refresh-token`,
{
method: "POST",
headers: new Headers(req.headers),
}
);
if (!response.ok) {
console.error("Failed to refresh access token");
return new Response("Failed to refresh access token", {
status: 500,
});
}
const newAccessToken =
(response.headers.get("Authorization") as string) || "";
console.log("New accessToken obtained: ", newAccessToken);
const res = NextResponse.next();
res.cookies.set({
name: "accessToken",
sameSite: "strict",
path: "/",
value: newAccessToken,
secure: process.env.NODE_ENV === "production",
});
return res;
} catch (error) {
if (error instanceof Response && error.status === 429) {
console.error("Rate-limited:", error.statusText);
return new Response("Rate limited: Too many requests", {
status: 429,
});
} else {
return new Response("Failed to refresh access token", {
status: 500,
});
}
}
} else {
// If refresh token is missing, return an error or handle it appropriately
return NextResponse.redirect(new URL("/login", req.url));
// return new Response("Refresh token is missing", { status: 401 });
}
}
// If access token is valid, allow the request to proceed without modification
return NextResponse.next();
}This however which is not in middleware works in every enviroment, including secure..
//Not middleware
export async function login(formData: FormData) {
// console.log(formData);
const response = await fetch(`${process.env.EXTERNAL_API}/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(Object.fromEntries([...formData])),
});
if (!response.ok) {
console.error("Error");
throw new Error("Failed to sign in: ", response as any);
}
const accessToken = response.headers.get("Authorization") ?? "";
const tokenParts = accessToken.split(" ");
const strippedAccessToken = tokenParts.length === 2 ? tokenParts[1] : "";
console.log("INITIAL ACCESSTOKEN: ", strippedAccessToken);
cookies().set("accessToken", strippedAccessToken, {
path: "/",
sameSite: "strict",
secure: process.env.NODE_ENV === "production",
});
const cookiesHeader = response.headers.get("set-cookie");
if (cookiesHeader) {
// Parse cookies
const cookiesArray = cookiesHeader.split("; ");
const refreshTokenCookie = cookiesArray.find((cookie) =>
cookie.startsWith("refreshToken=")
);
if (refreshTokenCookie) {
let refreshToken = refreshTokenCookie.split("=")[1];
cookies().set("refreshToken", refreshToken, {
path: "/",
sameSite: "strict",
httpOnly: true,
secure: process.env.NODE_ENV === "production",
});
console.log("User signed in: ", Object.fromEntries([...formData]).email);
}
}
}Elm sawflyOP
Bump
Elm sawflyOP
Bump
Elm sawflyOP
Bump
please only bump at most once a day
Toyger
something wrong with your root CA of your ssl, it's not presented in vercel edge runtime, you can try set NODE_TLS_REJECT_UNAUTHORIZED to 0
which not the best idea, but still possible solution
or add your domain certificate to NODE_EXTRA_CA_CERTS https://github.com/vercel/next.js/discussions/21854#discussioncomment-2396024
which not the best idea, but still possible solution
or add your domain certificate to NODE_EXTRA_CA_CERTS https://github.com/vercel/next.js/discussions/21854#discussioncomment-2396024
@Toyger something wrong with your root CA of your ssl, it's not presented in vercel edge runtime, you can try set NODE_TLS_REJECT_UNAUTHORIZED to 0
which not the best idea, but still possible solution
or add your domain certificate to NODE_EXTRA_CA_CERTS https://github.com/vercel/next.js/discussions/21854#discussioncomment-2396024
Elm sawflyOP
I tried env node tls extra certs and also ignorere tls, dont do anything except supress the errormsg. The fetch is still broken and not usable no mather what i do
@Elm sawfly I tried env node tls extra certs and also ignorere tls, dont do anything except supress the errormsg. The fetch is still broken and not usable no mather what i do
Toyger
what certificates are you using? rapidssl? letsencrypt? zerossl? etc
Elm sawflyOP
Every other fetch works fine, even to same endpoint outside middleware
Currently cloudflare between server and cloudflare and letsencrypt (generated by cloudflare) between CF and client
Tried letsencrypt aswell, and also selfsigned
@Elm sawfly Tried letsencrypt aswell, and also selfsigned
Toyger
letsencrypt without cloudflare?
selfsigned will 100% give error.
selfsigned will 100% give error.
Elm sawflyOP
Yes cloudflare i put on last just to see if full strict would do the trick
Howcome i dont gett that msg outside middleware?
I kinda have to go through CF due cgnat
Toyger
middleware use different runtime.
Full strict still uses CF certificate in front, it only check that origin certificate is ok
Full strict still uses CF certificate in front, it only check that origin certificate is ok
Elm sawflyOP
So hmm cloudflared argo tunnels letsencrypt certs are not valid for nextjs?
Toyger
you need to disable cloudflare proxying and test directly on origin with letsencrypt or zerossl
Elm sawflyOP
Dumb question. But can i turn of proxy while behind cgnat?
Toyger
if your origin available for cloudflare most likely it's not behind cgnat.
Elm sawflyOP
Its an argo tunnel, i dont have public ip
Using cloudflared you can start a tunnel, and tunnel services to cf
Ive done this with many services, just nextjs thats not working correctly
Toyger
hmm, ok, if you have argo tunnel then it's not a viable option.
ideally you should have public ipv4, right now you only can serve site with CF ssl.
as possible workaround maybe you can try
https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites
and use some path on site that will proxy your cf proxied url.
it's kinda additional hops, but still viable workaround, it should terminate ssl with vercel so error should gone.
ideally you should have public ipv4, right now you only can serve site with CF ssl.
as possible workaround maybe you can try
https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites
and use some path on site that will proxy your cf proxied url.
it's kinda additional hops, but still viable workaround, it should terminate ssl with vercel so error should gone.
Answer
Elm sawflyOP
Ahh cool i will check it out, anything special in my situation i should think about using rewrite?
Toyger
no, should be simple rewrite, and if you say url works not on middleware, so in rewrite situation it shouldn't cause error
Elm sawflyOP
roger, i will try it out and see if i get it to work
thanks so far!
been biting my nails for couple of days now hehe :p
Elm sawflyOP
omg i think it works! you are the man all week long @Toyger ! 😄