【问题标题】:Express-session cookie is being set in store but inaccessible in later API callsExpress-session cookie 正在存储中设置,但在以后的 API 调用中无法访问
【发布时间】:2022-12-06 04:28:12
【问题描述】:

我正在尝试使用 SERN 堆栈创建登录/注册系统,使用 express-session 确定用户是否登录。cookie 被保存到浏览器中,并发送到会话存储,并修改 cookie , 但无法通过其他途径访问。尽管 cookie 存在于浏览器和存储中,但它会继续在其他 API 调用中生成新会话。服务器托管在端口 5000 上,而 React 客户端托管在端口 3000 上。客户端调用使用 axios 进行,并使用 withCredentials:true 设置完成

数据库.js: `

const session=require("express-session");
    const config={
        connectionLimit:process.env.DB_CONNECTION_LIMIT,
        host:process.env.DB_HOST,
        user:process.env.DB_USER,
        password:process.env.DB_PASSWORD,
        database:process.env.DB_DATABASE
    }
    const db=mysql.createPool(config);
    const SQLStore=require("express-mysql-session")(session);
    const store=new SQLStore({
        expiration:7*24*3600*1000,
        createDatabaseTable:true,
        schema:{
            tableName:"Sessions",
            columnNames:{
                session_id:"session_id",
                expires:"expires",
                data:"session_data"
            }
        }
    },db);

服务器.js

const express=require('express');   
const app=express();

const cors=require('cors');
app.use(cors({
    origin:"http://localhost:3000",
    methods:["GET,POST"],
    credentials:true
}));

const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());

require('dotenv').config()

const dbExports=require('./databaseConnect');
const session=dbExports.session;
const store=dbExports.store;
const searchUserByInsertID=dbExports.searchUserByInsertID;
const searchUserByUsername=dbExports.searchUserByUsername;
const searchUserByUsernameAndEmail=dbExports.searchUserByUsernameAndEmail;
const createUser=dbExports.createUser;

const cookieParser=require("cookie-parser");
app.use(cookieParser());

app.use(session({
    name:process.env.SESSION_NAME,
    resave:false,
    saveUninitialized:false,
    store:store,
    secret:process.env.SESSION_SECRET,
    cookie:{
        secure:false,
        expires:14*24*60*60*1000
    }
}))

const bcrypt=require('bcrypt');
const validator=require("email-validator")
require("./routes")(app,validator,bcrypt,searchUserByInsertID,searchUserByUsername,searchUserByUsernameAndEmail,createUser);

app.listen(5000,()=>{
    console.log("listening on port 5000")
})

` 路由.js:

app.post('/login',async (req,res)=>{
        const username=req.body.username;
        const password=req.body.password;
        const user=await searchUserByUsername(username);
        if(!user.length){
            console.log("username not found in db");
            res.json({status:"usernameInvalid"});
        }
        else{
            const dbHashedPassword=user[0].password;
                    if(await bcrypt.compare(password,dbHashedPassword)){
                        req.session.user=user[0];
                        req.session.save();
                        console.log(req.session);
                        res.json({status:"userValid"});
                    }
                    else{
                        console.log("wrong password");
                        res.json({status:"passwordInvalid"});
                    }
        }
    })

//once the user is redirected to a landing page after registering/logging in, this route is called, but returns undefined, and console logging the sessionid shows a different value than the one that is currently in the browser cookie/store.
app.get('/checkSession',async (req,res)=>{
        console.log(req.session.user);
        res.json({status:"hi"});
    })

反应客户端中的api调用:

Axios.defaults.withCredentials=true;
    Axios.get('http://localhost:5000/checkSession').then((response)=>{
        console.log(response.data);
    }).catch((err)=>{
        console.log(err);
    })

browser session is created

session store also receives the session

我尝试修改会话设置,但无法通过不同的路由持续访问会话。一旦客户端发出后续请求,尽管浏览器中存在会话 cookie,但服务器无法访问它。

【问题讨论】:

    标签: node.js express express-session


    【解决方案1】:

    听起来您遇到了跨域资源共享 (CORS) 问题。当端口 3000 上的客户端向端口 5000 上的服务器发出请求时,如果服务器不包含适当的 CORS 标头,浏览器将阻止响应。

    要解决此问题,您可以将 CORS 中间件添加到您的 Express 服务器。这是您如何执行此操作的示例:

    const cors = require('cors')
    
    app.use(cors({
      origin: 'http://localhost:3000',
      credentials: true
    }))
    

    origin 属性应设置为将向服务器发出请求的客户端的 URL。 credentials 属性应设置为 true,以便服务器在其响应中包含 Access-Control-Allow-Credentials 标头。

    添加 CORS 中间件后,服务器将在其响应中包含适当的标头,并且客户端应该能够在后续请求中访问会话数据。

    希望这可以帮助!

    【讨论】:

    • 我已经用完整的 server.js 文件更新了 OP。我已经拥有证书为 true 的 cors 中间件,所以我无法判断这是客户端问题还是服务器问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2019-05-18
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多