Search code examples
node.jsvue.jsexpresssocket.ioexpress-session

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


im trying to create a simple app with a login just to play around with socketio, vue and nodejs (express), i got the sending and receiving to work on both the client and the server. But i got a problem when i try to integrate a session so i can keep a user logged in.

i tried many different modules nothing worked for me. I'm sure that there is just something i am not getting right now, since i'm pretty new to nodejs and all that.

anyway here is my code:

frontend:

<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>

Backend:

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...');
});

Basically what should happen is, that when a user is "logging in", his username gets saved to the session. And when the user refreshes the page, it should still be there. But at the moment, everytime the user refreshes the page, he geats a new session so everything is just gone.

hope someone can help me.


Solution

  • I tried your server code with client served through express.static, it works as expected. Gives the same sessionId even after refresh or on new tab.

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

    The client code, saved in 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>
    

    In your case you are serving your client files from different source. Express session will not work as you expect. Even for simple get request new session will be created. Try adding the below code to your server, and try a get request from your client, you will know what I mean

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