summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGravatar Piotr Russ <mail@pruss.it> 2020-11-26 22:20:54 +0100
committerGravatar Piotr Russ <mail@pruss.it> 2020-11-26 22:20:54 +0100
commitf2fcc41cb17ece1fc5acf57809c5e3d61c236133 (patch)
treea103a0dd371c5f7fd5d7e3105fef0730c8594827 /server
parent627239499c7c9fb5e7af68b2e79e01d0523f5d8f (diff)
downloadwebsite_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.js2
-rw-r--r--server/middleware/auth.js29
-rw-r--r--server/middleware/redirectLogged.js39
-rw-r--r--server/models/Session.js23
-rw-r--r--server/models/User.js33
-rw-r--r--server/routes/user.js33
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)