最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Unable to Set Cookies from Express.js to Next.js SSR Component (app router) - Stack Overflow

programmeradmin1浏览0评论

I have an Express.js backend running on http://localhost:8000 and a Next.js frontend (App Router) running on http://localhost:3000.

What Works: • When making a request from a Next.js client component (browser) to the Express backend, cookies are set successfully. • When checking the response headers in a server component (SSR) or API route, I can see the Set-Cookie header coming from Express.

What Works: • When making a request from a Next.js client component (browser) to the Express backend, cookies are set successfully. • When checking the response headers in a server component (SSR) or API route, I can see the Set-Cookie header coming from Express.

What I Tried: • Setting credentials: "include" in the fetch request. • Making a Next.js API route as a proxy and forwarding the Set-Cookie header. • Using different SameSite policies (Lax, Strict, None with Secure). • Ensuring CORS is properly configured on Express (Access-Control-Allow-Credentials: true). • Manually setting a cookie in the Next.js response (nextResponse.cookies.set("key", "value")).

This is my SSR function on NextJS to fetch request on ExpressJS API. To get info if user is authenticated or not I am sending access token. If access token is expired and refresh token is valid then I am refreshing the access token but new access token is not adding to browser cookies.

            "use server";
        import { User } from "@/components/providers/user.provider";
        import { cookies } from "next/headers";
        import { fetcher } from "./fetcher";

        interface invalidSession {
            ok: false, message: string, code: "unauthorized" | "invalid-or-expired-token"
        }

        interface successSession {
            ok: true, message: string, data: User;
        }


        export async function getSession() {
            const accessToken = (await cookies()).get("accessToken")?.value;
            const refreshToken = (await cookies()).get("refreshToken")?.value;

            const res = await fetcher<invalidSession | successSession>("/user/info", {
                headers: {
                    Cookie: `accessToken=${accessToken}`
                }
            });

            if (!res.ok) {

                if (res.code === "invalid-or-expired-token") {
                    console.log("Invalid or expired access token");
                    console.log("refreshing token");


                    const refreshTokenRes = await fetcher<invalidSession | successSession>("/user/refresh-token", {
                        method: "POST",
                        headers: {
                            Cookie: `refreshToken=${refreshToken}`
                        }
                    });


                    if (!refreshTokenRes.ok) {
                        console.log("refresh token is invalid or expired!");
                        return null;
                    } else {
                        console.log("refresh token is valid & generated new access token!");

                        return refreshTokenRes.data
                    }
                }

                console.log("No access Token is provided!");
                return null;
            }

            console.log("access token is valid!");
            return res.data;

        }

this is my expressjs refreshToken function where i setting new accessToken but it not working as i say above. it only works when request comes from nextjs client component but not when request comes from nextjs ssr

             public async refreshToken(req: Request, res: Response) {
                const refreshToken = req.cookies.refreshToken;

                if (!refreshToken) {
                    res.clearCookie("accessToken")
                    res.clearCookie("refreshToken")
                    return ResponseHandler.unauthorized(res, "unauthorized");
                };

                try {
                    const decoded = jwt.verify(refreshToken, authConfig.auth_refresh_secret) as { id: number };
                    const user = await prisma.user.findUnique({ where: { id: decoded.id }, include: { user_verifications: true } });

                    if (!user) {
                        res.clearCookie("accessToken")
                        res.clearCookie("refreshToken")
                        return ResponseHandler.unauthorized(res, "unauthorized")
                    };

                    const verifications = user.user_verifications as user_verifications;

                    const newAccessToken = jwt.sign({ id: user.id }, authConfig.auth_secret, {
                        expiresIn: `${authConfig.auth_secret_expires_in as any}m`
                    })

                    res.cookie("accessToken", "asd", {
                        httpOnly: true,
                        secure: process.env.NODE_ENV === "production" ? true : false,
                        sameSite: "strict",
                    });

                    return ResponseHandler.success(res, {
                        accessToken: newAccessToken,
                        user: {
                            firstname: user.firstname,
                            lastname: user.lastname,
                            email: user.email,
                            email_verified: verifications.email_verified,
                            email_verified_at: verifications.email_verified_at,
                            phone: user.phone,
                            phone_verified: verifications.phone_verified,
                            phone_verified_at: verifications.phone_verified_at,
                        }
                    })
                } catch (error) {
                    res.clearCookie("accessToken")
                    res.clearCookie("refreshToken")
                    return ResponseHandler.unauthorized(res, "unauthorized", "Invalid refresh token");
                }
            }
发布评论

评论列表(0)

  1. 暂无评论