Monday 9 November 2020

Is it safe to store socket.io sockets in a server object?

This might be a dumb question, but I am trying to explain it as simply as I can.

So I have been using axios to retrieve data from my server to my react app (redux) Since I use socket.io in my app a lot, I thought I could make the authentication use that as well, so I don't have to use axios and socket.io concurrently. I have been using PassportJS for authentication, but I can't wrap my head around how the socket.io passport packages I found on npm work.

I am using this socket.io-redux middleware to fire reducers on socket.io events. With this, I can dispatch actions that then get sent to the server, and from the server I can fire the reducers I want, in order to change the state.

Here is my store.js

import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
import { composeWithDevTools } from 'redux-devtools-extension';
import createSocketIoMiddleware from 'redux-socket.io';
import io from 'socket.io-client';
const socket = io('http://localhost:5000');
const socketIoMiddleware = createSocketIoMiddleware(socket, "io/");


const initialState = {};

const middleware = [thunk, socketIoMiddleware];

const store = createStore(
    rootReducer,
    initialState,
    composeWithDevTools(
        applyMiddleware(...middleware)
    )
);

// store.dispatch({type:'server/hello', data:'Hello!'});

export default store

Using this method a socket is created for every client upon connecting to the website. I created a Store class on the server side as well, with the the login/logout methods like so (these keep track of the clients and the users associated with them):

class Store
{
    constructor(){
        this.loggedInUsers = [];
    }

    loginUser(userID, socketID){
        console.log('login', userID, socket.id);
        
        const index = this.loggedInUsers.find(u => u.socketID !== socket.id && u.userID === userID);
        if(index >= 0){
            this.logoutUser(this.loggedInUsers[index].socketID);
        }
        
        this.loggedInUsers = [
            ...this.loggedInUsers, 
            {
                userID: userID,
                socketID: socket.id,
            }
        ];
    }

    logoutUser(socketID){
        console.log('logout', socketID);
        const index = this.loggedInUsers.find(u => u.socketID === socketID);
        if(index >= 0){
            this.loggedInUsers = [...this.loggedInUsers.slice(0, index), ...this.loggedInUsers.slice(index+1)];
        }
    }
}

module.exports.store = new Store();

On login a socket.io event is emmitted to the server, then on a successful login the socket gets stored in a loggedInUsers object that holds the user IDs and the sockets associated with them, then fires a reducer to store the authenticated state in my store. On logout, the user with the socket given gets removed from the object.

Now I am wondering if this is even safe to do or not.



from Is it safe to store socket.io sockets in a server object?

No comments:

Post a Comment