Home > Blockchain >  Adding Redis store to Express server causes strategy to not run
Adding Redis store to Express server causes strategy to not run

Time:01-30

Trying to add a redis store to my express server. When I run the server without adding the redisStore in the app.use(session(()) section I'm able to login without any problems. The issue is as soon as I add store: new RedisStore() the login will hang indefinitely and not call any of the console.logs inside my strategy.

Ive tried to figure out what could cause this but I've never had this issue before using a redis store. The redisclient connects successfully and outputs the console.log that it has connected so I have all of the correct server information.

Removed imports that arent important to make it easier to read

import * as express from 'express';
import { createServer } from 'http';
import * as cors from 'cors';
import * as session from 'express-session';
import * as passport from 'passport';
import { getFrontendURL } from './utils';
import * as connectRedis from 'connect-redis';
import { createClient } from 'redis';

require('./config/passport-local');
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();

const app = express();
const httpServer = createServer(app);
const port = process.env.PORT || 3333;


app.set('trust proxy', 1);

//Middleware
app.use(
  cors({
    origin: [getFrontendURL()],
    credentials: true,
  })
);

const redisClient = createClient({
  url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`,
  password: process.env.REDIS_PASSWORD,
});
redisClient.connect();

redisClient.on('connect', function (err) {
  console.log('Connected to redis successfully');
});

redisClient.on('error', function (err) {
  console.log('Could not establish a connection with redis. '   err);
});
const RedisStore = connectRedis(session);

app.use(
  session({
    store: new RedisStore({ client: redisClient }), //Commenting this out makes login work
    name: 'session-id',
    secret: '123-456-789',
    resave: false,
    saveUninitialized: false,
    // cookie: {
    //   httpOnly: true,
    //   secure: process.env.ENVIRONMENT === 'production' ? true : false,
    //   sameSite: process.env.ENVIRONMENT === 'production' ? 'none' : 'lax',
    //   maxAge: 24 * 60 * 60 * 7 * 1000,
    // },
    cookie: {
      secure: false, // if true only transmit cookie over https
      httpOnly: false, // if true prevent client side JS from reading the cookie
      maxAge: 1000 * 60 * 60 * 24 * 7, // ms * seconds * minutes * hours * days -> 7 days in miliseconds
    },
  })
);
app.use(passport.initialize());
app.use(passport.session());

const io = new Server(httpServer, {
  cors: { origin: [getFrontendURL()], credentials: true },
});
socketEventHandler(io);

app.use(express.json()); //Parses All incoming data into JSON
app.use(express.urlencoded({ extended: true })); //Allows us to retreive data from Form Submissions
//Routes
app.use('/api/auth', authRouter);
app.use('/api/member', memberRouter);

(async () => {
  const server = httpServer.listen(port, () => {
    console.log(`Listening at http://localhost:${port}/api`);
  });

  server.on('error', (err) => console.log(err));
})();

PASSPORT.js -> All console.log("Here") run without redis store added. None of them run when redisStore is added.

import { PrismaClient, User } from '@prisma/client';
import * as bcrypt from 'bcrypt';
import * as passport from 'passport';
import { Strategy as LocalStrategy } from 'passport-local';

const prisma = new PrismaClient();

passport.use(
  new LocalStrategy(async function (username: string, password: string, done) {
    let foundUser: User;
    console.log('HERE');

    try {
      foundUser = await prisma.user.findFirst({
        where: { username: { equals: username, mode: 'insensitive' } },
      });
    } catch (err) {
      return done(null, false, 'invalid');
      // return dne(null, new Error('No user registered with this username'));
    }
    console.log('HERE');

    if (!foundUser) return done(null, false, 'invalid');
    console.log('HERE');

    //Verify Password with BCrypt
    let validPass = false;
    try {
      validPass = bcrypt.compareSync(password, foundUser.password);
    } catch (err) {
      return done(null, false, 'invalid');
    }
    console.log('HERE');

    if (!validPass) {
      return done(null, false, 'invalid');
    }

    console.log('HERE');

    //Send Data Back
    return done(null, foundUser);
  })
);

passport.serializeUser((user: any, cb: any) => {
  console.log('HERE');

  cb(null, user.id);
});

passport.deserializeUser(async (id: number, cb: any) => {
  console.log('HERE');

  const user = await prisma.user.findUnique({ where: { id } });
  if (!user) return cb(null, false); //Throw Error // Delete Session
  cb(null, user);
});

Login Auth Router HERE does not get ran when using redisstore

router.post(
  '/login',
  passport.authenticate('local', {
    successRedirect: 'user',
    failureRedirect: 'failed',
  }),
  (_, res) => {
    console.log('HERE');
    res.sendStatus(200);
  }
);

router.post('/logout', logout);
router.get('/user', user);
router.get('/failed', failed);

CodePudding user response:

connect-redis only supports v4 with legacyMode. See here.

  • Related