Node.js(Express)为后台的Next.js中未设置Cookie

cig3rfwq  于 2023-04-05  发布在  Node.js
关注(0)|答案(1)|浏览(144)

我按照本教程在我的项目中使用HTTP-Only cookie:https://maxschmitt.me/posts/next-js-http-only-cookie-auth-tokens
后端工作正常,我可以在Postman中看到cookie。但作为参考,我将发布后端代码:(注:安全:true为hashed)

router.post('/login', upload.none(), async (req, res, next) => {

    const { username, password } = req.body;

    if (password != "12345678") {
        return res.status(401).send({
            message: `You're not authorized!`,
            success: false
        })
    }
    const admin_id = "1";

    const payload = { id: admin_id, role: "admin" };
    const jwt = JWT.sign(payload, secret, { algorithm: 'HS256', expiresIn: "7d" });

    res.cookie( "token", jwt, {
        httpOnly: true,
        // secure: true // only works on https
    });

    return res.status(200).send({
        message: 'Logged in!',
        success: true
    });
});

前端:
管理员登录服务:

const adminLogin = async (url: string, data: any) => {

    const { arg: { username, password } } = data;

    let formData = new FormData();
    formData.append("username", username);
    formData.append("password", password);

    try {
        const result = await axios.post(url, formData, { headers: { "Content-Type": "multipart/form-data" } });
        console.log(result);
        return result.data;
    } catch (error) {
        const err = error as AxiosError;
        return err.response!.data;
    }
};

登录页面:(我使用的是SWR包,onLogin在LoginPage组件中)

const { trigger, isMutating } = useSWRMutation("http://localhost:8000/api/v1/admins/login", adminLogin);

const onLogin = async (data: any) => {
        const response = await trigger(data);

        if (response.success === true) {
            console.log(response);
        } else {
            setErrorMsg(response.message);
            setOpenAlertDialog(true);
        }
    };

next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: true
};

module.exports = {
    async rewrites() {
        return [{
            source: "/api/v1/:path*",
            destination: "http://localhost:8000/api/v1/:path*"
        }];
    }
};

module.exports = nextConfig;

API/[...path].ts:

import httpProxy from "http-proxy";
import Cookies from "cookies";
import url from "url";

const proxy = httpProxy.createProxyServer();

export const config = {
    api: {
        bodyParser: false
    }
};

const main = (req: any, res: any) => {
    return new Promise<void>((resolve, reject) => {
        const pathname = url.parse(req.url).pathname;
        const isLogin = pathname === "/api/login" || pathname === "/api/v1/admins/login";

        const cookies = new Cookies(req, res);
        const authToken = cookies.get("token");

        req.url = req.url.replace(/^\/api/, "");

        req.headers.cookie = "";

        if (authToken) {
            req.headers["token"] = authToken;
        }

        if (isLogin) {
            proxy.once("proxyRes", interceptLoginResponse);
        }

        proxy.once("error", reject);
        proxy.web(req, res, {
            target: "http://localhost:8000/api/v1",
            autoRewrite: false,
            selfHandleResponse: isLogin
        });

        function interceptLoginResponse(proxyRes: any, req: any, res: any) {
            let apiResponseBody = "";
            proxyRes.on("data", (chunk: any) => {
                apiResponseBody += chunk;
            });

            proxyRes.on("end", () => {
                try {
                    const { authToken } = JSON.parse(apiResponseBody);

                    const cookies = new Cookies(req, res);
                    cookies.set("token", authToken, {
                        httpOnly: true,
                        sameSite: "lax",
                        path: "/"
                    });

                    res.status(200).json({ loggedIn: true });
                    resolve();
                } catch (err) {
                    reject(err);
                }
            });
        }
    });
};

export default main;

我错过了什么,我如何从我的本地机器上的next.js中的登录功能中的后端cookie?我需要在我的生产设置中进行哪些更改?(我将在我的服务器上使用NginX)。
先谢了...

ffscu2ro

ffscu2ro1#

您没有告诉axios设置cookie,所以它只是忽略它得到的任何cookie

try {
        const result = await axios.post(url, formData, { headers: { "Content-Type": "multipart/form-data" },withCredentials: true });
        console.log(result);
        return result.data;
    } catch (error) {
        const err = error as AxiosError;
        return err.response!.data;
    }

相关问题