使用 socket.io 的 Express Session 和值在每次页面加载时重置

Express Session with socket.io and vue gets reset on every pageload

我正在尝试创建一个带有登录名的简单应用程序,只是为了玩弄 socketio、vue 和 nodejs (express),我在客户端和服务器上都可以进行发送和接收。 但是当我尝试集成一个会话以便让用户保持登录时我遇到了问题。

我尝试了很多不同的模块,但没有一个对我有用。我确定我现在还没有得到一些东西,因为我对 nodejs 和所有这些还很陌生。

无论如何这是我的代码:

前端:

<template>
    <div>
        <p>
            <input type="text" name="username" id="username" v-model="user.username" placeholder="Username" /><br />
            <input type="password" name="password" id="password" v-model="user.password" placeholder="Password" /><br />
            <button v-on:click="register()">Register</button>
        </p>
    </div>
</template>

<script>
import io from 'socket.io-client';

export default {
    name: 'BlockGame',
    data() {
        return {
            user: {
                username: '',
                password: '',
            },
            socket: {},
            context: {},
        };
    },
    created() {
        this.socket = io('localhost:3000', {
            withCredentials: true,
        });
    },
    mounted() {
        this.socket.on('', (data) => {});
    },
    methods: {
        register() {
            this.socket.emit('register-user', this.user);
        },
    },
};
</script>

<style scoped></style>

后端:

const app = require('express')();
const redis = require('redis');
const server = require('http').createServer(app);
const session = require('express-session');
const socketio = require('socket.io')(server, {
    cors: {
        origin: 'http://localhost:8080',
        methods: ['GET', 'POST'],
        preflightContinue: false,
        optionsSuccessStatus: 204,
        credentials: true,
    },
});
let RedisStore = require('connect-redis')(session);
let redisClient = redis.createClient();

var sessionMiddleware = session({
    name: 'session_cookie',
    secret: 'edfafewfdsfezhrjew',
    store: new RedisStore({ client: redisClient }),
    resave: false,
    saveUninitialized: true,
    cookie: { maxAge: 1000 * 60 * 5, secure: false },
});

app.use(sessionMiddleware);

socketio.use((socket, next) => {
    sessionMiddleware(socket.request, {}, next);
});

socketio.on('connect', (socket) => {
    const session = socket.request.session;
    console.log(session.id);
    if (session.user) {
        console.log('----- SESSION -----');
        console.log('Session ID: ' + session.id + ' / Session User: ' + session.user);
    }

    socket.on('register-user', (data) => {
        const session = socket.request.session;
        session.user = data['username'];

        session.save();
        console.log(session);
    });
});

server.listen(3000, () => {
    console.log('Listening at :3000...');
});

基本上应该发生的是,当用户“登录”时,他的用户名被保存到会话中。当用户刷新页面时,它应该仍然存在。但目前,每次用户刷新页面时,他都会获得一个新会话,所以一切都消失了。

希望有人能帮助我。

我尝试了您的服务器代码,客户端通过 express.static 提供服务,它按预期工作。即使在刷新后或在新选项卡上也提供相同的 sessionId。

app.use(express.static("public"))

客户端代码,保存在public/index.html

<!doctype html>
<html>
    <head>
        <script src='/socket.io/socket.io.js'></script>
        <script>
            var socket = io("/",{withCredentials: true,});
            socket.on('connect', ()=>{
                socket.emit('register-user', {username:"User Name"});
                document.write("Connected")

            })
           
        </script>
    </head>
</html>

在您的情况下,您正在为来自不同来源的客户端文件提供服务。 快速会话将不会像您预期的那样工作。即使对于简单的获取请求,也会创建新会话。尝试将以下代码添加到您的服务器,并尝试从您的客户端获取请求,您就会明白我的意思

app.use((req,_,next)=>{
    console.log(req.session.id)
    next()
})