如何从后端发送仅http的cookie

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

我正在尝试使用 JWT 令牌和仅 HTTP cookie 与 Express.js 为管理面板创建身份验证。当我从前端发送请求时,它给出了成功的响应,但不返回任何 cookie。但是,当我尝试来自 Postman 的相同请求时,它会按预期返回 cookie。

const handleSubmit = async (e) => {
    e.preventDefault();
    if (loading) return;
    setLoading(true); // Start loading

    try {
        const response = await axios.post(
            `${import.meta.env.VITE_BACKEND_URI}/adminLogin`,
            { Id: id, Password: password }
        );

        if (response.status === 200) {
            navigate('/Home');
        }
    } catch (error) {
        setError(error.response?.data?.error || "Login failed. Please check your internet or try again later.");
    } finally {setLoading(false);}
};

点击提交按钮后,我被重定向到/Home路线。

下面是我创建和发送 cookie 的 api 端点

import express from 'express';
import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';

dotenv.config();
const router = express.Router();

router.post('/', (req, res) => {
    try {
        const { Id, Password } = req.body;

        console.log(process.env.ADMIN_ID === String(Id));
        console.log(process.env.ADMIN_PASSWORD === String(Password));
        
        if (process.env.ADMIN_ID === String(Id) && process.env.ADMIN_PASSWORD === String(Password)) {
            const token = jwt.sign({ id: Id, password: Password }, process.env.JWT_SECRET, { expiresIn: '1h' });
            
            res.cookie("jwtToken", token, {
                httpOnly: true,
                secure: process.env.NODE_ENV === 'production', 
                sameSite: "Lax",
                maxAge: 3600 * 1000,
                path: '/', 
            });
            
            console.log("correct");
            res.sendStatus(200);
        } else {
            res.status(401).json({ error: "invalid credentials" });
        }
    } catch (error) {
        console.log(error);
        res.status(500).json({ error: "Internal Server Error" });
    }
});

export default router;

这是我的 server.js 文件,我认为它包含所有必需的中间件,如果我缺少任何中间件,请告诉我

import express from "express";
import bodyParser from "body-parser";
import cookieParser from 'cookie-parser';
import cors from "cors";
import dotenv from "dotenv";
import connectDB from "./config/db.js";
import loginRoute from "./routes/Login.js";
import signUpRoute from "./routes/SignUp.js";
import authorizationRoute from "./routes/Authorize.js";
import deleteUserRoute from "./routes/deleteUser.js";
import sendEmailRoute from "./routes/Subscriber.js";
import sendInquiriesRoute from "./routes/Inquiries.js";
import adminLoginRoute from "./routes/AdminLogin.js";
import tokenRoute from "./middleware/auth.js";

dotenv.config();
connectDB();

const server = express();
const port = process.env.PORT_NO || 3000;

server.use(bodyParser.json());
server.use(cookieParser());

server.use(cors({
    origin: ["http://localhost:4000", "http://localhost:5173"],
    credentials: true,
}));

// Home route
server.get('/', (req, res) => {
    res.send("this is home route");
});

// Use the routes
server.use('/login', loginRoute);
server.use('/signUp', signUpRoute);
server.use('/authorizeEmail', authorizationRoute);
server.use('/deleteUser', deleteUserRoute);
server.use('/sendEmail', sendEmailRoute);
server.use('/sendInquiries', sendInquiriesRoute);
server.use('/adminLogin', adminLoginRoute);
server.use("/checkToken", tokenRoute);

server.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

此外,如果我将后续请求发送到以下端点

import express from 'express';
import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';

dotenv.config();

const router = express.Router();

router.get('/', (req, res) => {
    const token = req.cookies.jwtToken;
    console.log(token)
    
    if (!token) {
        return res.status(401).json({ error: "Authentication token missing" });
    }

    jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
        if (err) {
            return res.status(403).json({ error: "Invalid or expired token" });
        }

        return res.sendStatus(200)
    });
});

导出默认路由器;

我在控制台中收到“身份验证令牌丢失”

reactjs node.js express jwt cookie-httponly
1个回答
0
投票

确保 Axios 随请求发送 Cookies

在 Axios 请求中添加

withCredentials: true
,以确保跨域请求发送 cookie。

像这样更新你的前端代码:

const handleSubmit = async (e) => {
    e.preventDefault();
    if (loading) return;
    setLoading(true); // Start loading

    try {
        const response = await axios.post(
            `${import.meta.env.VITE_BACKEND_URI}/adminLogin`,
            { Id: id, Password: password },
            { withCredentials: true } // Ensures cookies are sent with the request
        );

        if (response.status === 200) {
            navigate('/Home');
        }
    } catch (error) {
        setError(error.response?.data?.error || "Login failed. Please check your internet or try again later.");
    } finally {
        setLoading(false);
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.