Add more details to NodeJS Redis sessions

I’m using NodeJS and Redis for my sessions.
Is there a way to add more information to the value Wappler sets in Redis for each session? I’d like to add the user’s location, device, etc. Or can I get the sessionID Wappler adds to Redis right after login to add these details to Redis myself?

You could just explicitly add the $_SERVER object to each session and go from there. It’s got pretty much everything of value

Yes, that’s where I’m getting most of the details from. But I need to get the session value that gets added to Redis by Wappler in order to kill specific sessions when a user requests that. So I’d either need to get that value and store it in my db or add a value that I can identify to each session in Redis.

I solved this by writing an express middleware. It stores the IP, user-agent & UUID in the Wappler Redis session.

The UUID can then be accessed via Wappler’s server connect $SERVER.uuid.

This allows to clear specific session for a user and add as much info as you want when the session is created via middleware:

const Redis = require("ioredis");
const { v4: uuid } = require("uuid");

exports.handler = function (app) {
  app.use(function (req, res, next) {
    const userIp = req.connection.remoteAddress;
    const sessionId = "sess:" + req.sessionID;
    const userAgent = req.headers["user-agent"];

    const redis = new Redis({
      port: process.env.REDIS_PORT,
      host: process.env.REDIS_HOST,
      password: process.env.REDIS_PASSWORD,
      user: process.env.REDIS_USER,
      db: 0,
      tls: {},
    });

    redis.get(sessionId, function (err, sessionData) {
      if (err) {
        console.error(err);
        return next();
      }

      let session = {};
      if (sessionData) {
        try {
          session = JSON.parse(sessionData);
        } catch (e) {
          console.error(e);
          return next();
        }
      }

      if (!session.uuid) {
        session.uuid = uuid();
        session.userIp = userIp;
        session.userAgent = userAgent;

        redis.set(sessionId, JSON.stringify(session), function (err) {
          if (err) {
            console.error(err);
          } else {
            console.log("Session data updated in Redis");
          }

          next();
        });
      } else {
        next();
      }
    });
  });
};

I’m using it for this:

5 Likes

Hi @tbvgl

This codes work perfectly, but I don’t know if is a normal behavior that every time the page load or even in rest mode it create a different sessionId inside redis server too much times, e.g.

If user keep in page in rest mode only watching info without refreshing or opening any link, in redis show up like 30 records wihout any user intervention.

If user navigete in page, in my case a admin user in dashboard, in a specific page for analitics porpuse and let the page in rest mode it create like 500 records, and that’s only one connected user.

RedisInsight recommends in Analysis Tool this:

Could this be the problem? Writing in ChatGTP in Edge Browser it recommend this based on your code:

In the provided code, a new Redis connection is created for every request, which can be an expensive operation and cause latency. One way to avoid this is to create a single Redis connection outside of the middleware function and reuse it for all requests. This can be done by moving the const redis = new Redis({...}) line outside of the app.use function and referencing the same redis variable within the middleware function. This way, the same Redis connection will be used for all requests, avoiding the need to create a new connection for each request.

While writing this post redis server counts 816 Connected clientes and 790 keys created with the site in total rest, even without focus the tab all this in localhost.

image

The same using Wappler Redis CLI:
image

Writing info I get:

# Clients
connected_clients:882
cluster_connections:0
maxclients:10000
client_recent_max_input_buffer:8
client_recent_max_output_buffer:0
blocked_clients:0
tracking_clients:0
clients_in_timeout_table:0

Thanks in advance

I’m interested in implementing this functionality. Is the multiple connections expected or an issue?

Based on the same Redis recommendation, that’s a problem, I ended up creating my own custom extension for Redis.

Yeah this is a problem. The code I posted above was just a draft. As chatGPT mentioned move the Redis connection outside of the middleware or even better use the existing Redis connection Wappler creates which is stored in the app.

1 Like