diff options
author | 2020-11-26 22:20:54 +0100 | |
---|---|---|
committer | 2020-11-26 22:20:54 +0100 | |
commit | f2fcc41cb17ece1fc5acf57809c5e3d61c236133 (patch) | |
tree | a103a0dd371c5f7fd5d7e3105fef0730c8594827 /server | |
parent | 627239499c7c9fb5e7af68b2e79e01d0523f5d8f (diff) | |
download | website_creator-f2fcc41cb17ece1fc5acf57809c5e3d61c236133.tar.gz website_creator-f2fcc41cb17ece1fc5acf57809c5e3d61c236133.tar.bz2 website_creator-f2fcc41cb17ece1fc5acf57809c5e3d61c236133.zip |
completed jwt token login with refresh token, reduced db calls
Diffstat (limited to 'server')
-rw-r--r-- | server/helpers/setCookie.js | 2 | ||||
-rw-r--r-- | server/middleware/auth.js | 29 | ||||
-rw-r--r-- | server/middleware/redirectLogged.js | 39 | ||||
-rw-r--r-- | server/models/Session.js | 23 | ||||
-rw-r--r-- | server/models/User.js | 33 | ||||
-rw-r--r-- | server/routes/user.js | 33 |
6 files changed, 83 insertions, 76 deletions
diff --git a/server/helpers/setCookie.js b/server/helpers/setCookie.js index bb3580c..6d6e7e8 100644 --- a/server/helpers/setCookie.js +++ b/server/helpers/setCookie.js @@ -2,7 +2,7 @@ const setCookie = function (res, path, stat) { if (res.req.newToken){ res.set( 'Set-Cookie', - 'token='+res.req.newToken+';httpOnly;MaxAge='+process.env.COOKIE_MAX_AGE+';Path=/' + 'token='+res.req.newToken+';httpOnly;Max-Age='+process.env.COOKIE_MAX_AGE+';SameSite=Strict;Path=/' ); } } diff --git a/server/middleware/auth.js b/server/middleware/auth.js index 5c77830..f012054 100644 --- a/server/middleware/auth.js +++ b/server/middleware/auth.js @@ -1,5 +1,5 @@ const jwt = require('jsonwebtoken'); -const User = require('../models/User'); +const Session = require('../models/Session'); const auth = async (req, res, next) => { try { @@ -10,27 +10,26 @@ const auth = async (req, res, next) => { } try { - const decoded = jwt.verify(token, process.env.JWT_SECRET); - req.userId = decoded._id; - req.refreshToken = decoded.ref; + const {sessionId, user} = jwt.verify(token, process.env.JWT_SECRET); + req.sessionId = sessionId; + req.loggedUser = JSON.parse(user); return next(); + } catch(er) { if (er.message && er.message === 'jwt expired') { - const { _id, ref } = jwt.decode(token, process.env.JWT_SECRET); - const user = await User.findById(_id); + const {sessionId, user} = jwt.decode(token); + const userData = JSON.parse(user); + const session = await Session.findById(sessionId); - if (!user) { + if (!session || session.userId.toString() !== userData.userId) { throw new Error(); } - if (user.sessions.filter(s => s.ref === ref).length > 0) { - req.userId = _id; - req.refreshToken = ref; - req.newToken = await user.generateJwtToken(ref);; - return next(); - } - - throw new Error(); + session.setAccessDate(); + req.newToken = session.generateJwtToken(userData);; + req.sessionId = sessionId; + req.loggedUser = userData; + return next(); } throw new Error(); diff --git a/server/middleware/redirectLogged.js b/server/middleware/redirectLogged.js index 40a5657..7d06ece 100644 --- a/server/middleware/redirectLogged.js +++ b/server/middleware/redirectLogged.js @@ -1,37 +1,42 @@ const jwt = require('jsonwebtoken'); const User = require('../models/User'); +const Session = require('../models/Session'); const redirectLogged = async (req, res, next) => { + console.log('redirectLogged') try { const token = req.cookies.token || ''; - if (!token) { throw new Error(); } try { - const decoded = jwt.verify(token, process.env.JWT_SECRET); - res.redirect('/admin'); + const token = jwt.verify(token, process.env.JWT_SECRET); + if (!token.user || !token.user.userId){ + throw new Error(); + } + return res.redirect('/admin'); } catch(er) { if (er.message && er.message === 'jwt expired') { - const { _id, ref } = jwt.decode(token, process.env.JWT_SECRET); - const user = await User.findById(_id); + const {sessionId, user} = jwt.decode(token); + const userData = JSON.parse(user); + const session = await Session.findById(sessionId); - if (!user) { + if (!session || session.userId.toString() !== userData.userId) { throw new Error(); } - if (user.sessions.filter(s => s.ref === ref).length > 0) { - const newToken = await user.generateJwtToken(ref);; - res - .cookie('token', token, { - maxAge: parseInt(process.env.COOKIE_MAX_AGE), - secure: false, - httpOnly: true, - }) - .redirect('/admin'); - } - + session.setAccessDate(); + const newToken = session.generateJwtToken(userData); + + return res + .cookie('token', newToken, { + maxAge: parseInt(process.env.COOKIE_MAX_AGE), + secure: false, + SameSite: 'Strict', + httpOnly: true, + }) + .redirect('/admin'); throw new Error(); } diff --git a/server/models/Session.js b/server/models/Session.js index c410bb9..06a4369 100644 --- a/server/models/Session.js +++ b/server/models/Session.js @@ -1,20 +1,31 @@ const mongoose = require("mongoose"); +const jwt = require('jsonwebtoken'); const sessionSchema = new mongoose.Schema({ - user: { + userId: { type : mongoose.Schema.Types.ObjectId, ref : 'User' }, - refreshToken: { - type: String, - required: true - }, lastAccess: { type: Date, default: Date.now(), - index: { expires: 90 } + index: { expires: parseInt(process.env.DB_SESSION_MAX_AGE) } } }); +sessionSchema.methods.setAccessDate = function (user) { + this.lastAccess = Date.now(); + console.log('refreshing time in db') + this.save(); +} + +sessionSchema.methods.generateJwtToken = function (user) { + return jwt.sign( + { sessionId: this._id.toString(), user: JSON.stringify(user) }, + process.env.JWT_SECRET, + { expiresIn: parseInt(process.env.JWT_TOKEN_MAX_AGE) } + ); +}; + module.exports = mongoose.model('Session', sessionSchema); diff --git a/server/models/User.js b/server/models/User.js index ef3d94e..02cfe25 100644 --- a/server/models/User.js +++ b/server/models/User.js @@ -1,8 +1,5 @@ const mongoose = require("mongoose"); const bcrypt = require('bcryptjs'); -const randtoken = require('rand-token'); -const jwt = require('jsonwebtoken'); -const Session = require('./Session'); const userSchema = new mongoose.Schema({ email: { @@ -25,31 +22,13 @@ const userSchema = new mongoose.Schema({ min: 4, max: 1024, }, -}); - -userSchema.methods.generateJwtToken = async function (currentRefToken) { - const refreshToken = currentRefToken ? currentRefToken : randtoken.uid(256); - - if (!currentRefToken) { - const session = new Session({ user: this, refreshToken }); - await session.save(); + language: { + type: String, + required: true, + min: 2, + max: 2, } - - return jwt.sign( - { _id: this._id.toString(), refreshToken }, - process.env.JWT_SECRET, - { expiresIn: parseInt(process.env.JWT_TOKEN_MAX_AGE) } - ); -} - -userSchema.methods.endSession = async function (ref) { - this.sessions = this.sessions.filter((session) => { - return session.ref !== ref; - }); - - await this.save(); - return null; -} +}); userSchema.statics.findByCredentials = async (email, password) => { const user = await User.findOne({ email }); diff --git a/server/routes/user.js b/server/routes/user.js index f2420ab..ee216ac 100644 --- a/server/routes/user.js +++ b/server/routes/user.js @@ -1,16 +1,16 @@ const router = require('express').Router(); const User = require('../models/User'); +const Session = require('../models/Session'); const auth = require('../middleware/auth'); const jwt = require('jsonwebtoken'); -router.get('/me', auth, async (req, res) => { - const user = await User.findById(req.userId); - - if (!user) { - res.clearCookie('token').redirect('/login'); +router.get('/me', auth, (req, res) => { + if (req.loggedUser) { + console.log(req.loggedUser) + return res.json(req.loggedUser); } - res.json({ email: user.email }); + return res.clearCookie('token').redirect('/login'); }) router.post('/register', async (req, res) => { @@ -33,10 +33,24 @@ router.post('/register', async (req, res) => { router.post('/login', async (req, res) => { try { const user = await User.findByCredentials(req.body.email, req.body.password); - const token = await user.generateJwtToken(); + if (!user) { + throw new Error(); + } + + const session = new Session({ userId: user._id }); + await session.save(); + + const publicUserData = { + userId: user.id, + email: user.email, + language: user.language + }; + + const token = session.generateJwtToken(publicUserData); + res .cookie('token', token, { - maxAge: parseInt(process.env.COOKIE_MAX_AGE), + maxAge: (1000 * parseInt(process.env.COOKIE_MAX_AGE)), secure: false, httpOnly: true, }) @@ -49,8 +63,7 @@ router.post('/login', async (req, res) => { router.post('/logout', auth, async (req, res) => { try { - const user = await User.findById(req.userId); - await user.endSession(req.refreshToken); + await Session.findByIdAndRemove(req.sessionId); res .clearCookie('token') .status(204) |