以Node.js(Express)为后端的Next.js中未设置Cookies

问题描述 投票:0回答:2

我按照本教程在我的项目中使用 HTTP-Only cookie: https://maxschmitt.me/posts/next-js-http-only-cookie-auth-tokens

后端工作正常,我可以在 Postman 中看到 cookie。但作为参考,我将发布后端代码:(注意:secure:true已散列)

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/[...路径].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)。

提前致谢...

reactjs cookies next.js
2个回答
0
投票

您没有告诉 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;
    }

0
投票

在前端登录服务文件中设置“使用客户端”。

'use client';

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

© www.soinside.com 2019 - 2024. All rights reserved.