Working sample of JWT base authentication api

122 views
Skip to first unread message

Klaudiusz Marszałek

unread,
Jul 16, 2018, 12:44:26 PM7/16/18
to Keystone JS
Hi,

Below is my JWT authentication sample which I would like to discuss with you. It works well but maybe there is a way to do that better. I will show you how it works and let me know if there's better way to do it.

routes/views/session/signinjwt.js


var keystone = require('keystone'),
    async = require('async'),
    jwt = require('jsonwebtoken'),
_ = require('lodash'),
crypto = require('crypto'),
utils = require('keystone-utils');
exports = module.exports = function(req, res) {
    
    if (req.user && req.cookies.uToken) {
        return res.redirect(req.cookies.target || '/me');
    }
    
    var view = new keystone.View(req, res),
        locals = res.locals;
     locals.section = 'session';
locals.form = req.body;

    view.on('post', { action: 'signinjwt' }, function(next) {
        
        if (!req.body.email || !req.body.password) {
            req.flash('error', 'Please enter your username and password.');
            return next();
        }
        
var token = '',
  userdata = {};
async.series([  
function (next) {
var User = keystone.list(keystone.get('user model'));
if (typeof req.body.email === 'string' && typeof req.body.password === 'string') {
if (!utils.isEmail(req.body.email)) {
return next({message:'Incorrect email or password'});
}
var emailRegExp = new RegExp('^' + utils.escapeRegExp(req.body.email) + '$', 'i');
User.model.findOne({ email: emailRegExp }).exec(function (err, user) {
if (user) {
user._.password.compare(req.body.password, function (err, isMatch) {
if (!err && isMatch) {
userdata = user;
return next();
} else {
return next({ message: err || 'Incorrect email or password' });
}
});
} else {
return next({ message: err });
}
});
} else {
return next({ message: 'Incorrect user or password'});
}
},
function(next) {
token = jwt.sign({id: userdata._id, email:userdata.email}, keystone.get('jwt secret'), { expiresIn: '15s' });
keystone.app.locals.user = userdata;
return next();
},
function(next) {
res.cookie('uToken', token, { maxAge: 900000, httpOnly: true });
res.clearCookie('afterLoginUrl');   
return next();
},
function(next) {
if (req.body.target && !/join|signinjwt/.test(req.body.target)) {
return res.redirect(req.body.target);
return next();  
} else {
var afterLoginUrl = req.cookies.afterLoginUrl || '/me';
return res.redirect(afterLoginUrl);
return next();
}
}
], function(err) {
if (err) {
req.flash('error', err.message || 'Sorry, there was an issue signing you in, please try again.');
return res.redirect('/signinjwt');
}
});
    });
    
    view.render('session/signinjwt');
    
}


routes/views/session/signoutjwt.js


var keystone = require('keystone');

exports = module.exports = function(req, res) {
    
    var view = new keystone.View(req, res),
        locals = res.locals;
    
    locals.section = 'session';
    res.clearCookie('uToken');
    keystone.app.locals.user = null;
    
    res.redirect('/');
};


routes/middleware.js


...

exports.initLocals = function (req, res, next) {
...

locals.user = keystone.app.locals.user;

...

}

...

exports.jwtCheck = function (req, res, next) {
    if (!req.cookies.uToken) {
        req.user = null;
        res.cookie('afterLoginUrl', req.originalUrl, { maxAge: 900000, httpOnly: true });
        req.flash('error', 'Please sign in to access this page.');
        res.redirect('/signinjwt');
    } else {
        
        jwt.verify(req.cookies.uToken, keystone.get('jwt secret'), function(err, decoded) {
            if(err) {
                req.user = null;
                res.clearCookie('uToken');
                res.cookie('afterLoginUrl', req.originalUrl, { maxAge: 900000, httpOnly: true });
                req.flash('error', 'Please sign in to access this page.');
                res.redirect('/signinjwt');
            } else {
                
                next();
            }
            
        });
    }
};
...


/routes/index.js

...

app.all('/signinjwt', routes.views.session.signinjwt);
    app.get('/signoutjwt', routes.views.session.signoutjwt);
app.all('/needauth*', middleware.jwtCheck);

...


/keystone.js


...

keystone.init({
...
'session': false,
...
});

...


/
Reply all
Reply to author
Forward
0 new messages