Last active
September 9, 2022 22:02
-
-
Save georgeben/e60f9fdac57dd05404eb4b6f70c6a7d2 to your computer and use it in GitHub Desktop.
Implementing sessions for authentication using redis
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const session = require('express-session') | |
const redis = require('redis') | |
const RedisStore = require('connect-redis')(session); | |
const uuid = require("uid-safe"); | |
const app = express() | |
const redisClient = redis.createClient({ legacyMode: true, url: 'your-redis-url-from-redis-cloud' }) | |
redisClient.connect() | |
redisClient.on("ready", () => console.log("Successfully connected to redis")); | |
// How long a user's session should last, before they would be required to login again | |
const sessionTimeout = 2 * 60 * 1000 | |
app.use(express.json()) | |
app.use(session({ | |
secret: 'a-secure-secret', | |
name: 'my-app-session', | |
// Store the session id as a cookie on the user's browser | |
cookie: { | |
httpOnly: true, | |
secure: true, | |
sameSite: true, | |
maxAge: sessionTimeout // How long a session should last in milliseconds | |
}, | |
resave: false, | |
store: new RedisStore({ | |
client: redisClient, | |
}), | |
saveUninitialized: false, | |
genid: (request) => { | |
/** | |
* This generates a unique session id. We are using the user id as | |
* a prefix to the session id. This makes it easy to retrieve all active | |
* sessions for a user. | |
*/ | |
const userId = request.userId ? request.userId : 0; | |
return `${userId}-${uuid.sync(24)}`; | |
}, | |
})) | |
app.post('/login', async (req, res) => { | |
const { email, password } = req.body; | |
const sampleUser = { | |
name: 'John Dorian', | |
email: '[email protected]', | |
password: 'iloveturk' | |
} | |
if (email !== sampleUser.email || password !== sampleUser.password) { | |
return res.status(401).json({ | |
message: 'Invalid email or password' | |
}) | |
} | |
/** | |
* Login is successful | |
* Regenerating a session destroys the current session and generates a new | |
* session id. This prevents session fixation attacks | |
*/ | |
req.session.regenerate((err) => { | |
if (err) { | |
// Handle error | |
} | |
// Store the authenticated user information in the session | |
req.session.user = sampleUser | |
req.session.save((err) => { | |
if (err) { | |
// Handle error | |
} | |
return res.status(200).json({ | |
message: 'Login successful', | |
user: { | |
name: sampleUser.name, | |
email: sampleUser.email, | |
} | |
}) | |
}) | |
}) | |
}) | |
app.post('/logout', async (req, res) => { | |
req.session.destroy() | |
}) | |
app.listen(5000, () => console.log('App running')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment