Wednesday, 26 April 2017

Keeping login and logout times with JWT

I have asked previously the following question,but I didn't get an answer.

Destroying JSON Web Tokens

I want to put in my database the time that the user logged in and logged out. However,I can not find any way doing that using the JSON Web Token. When the user registers in the db(I use mongoDB),all of his data are stored. Maybe the login/logout times are encoded inside the payload of the token. I don't know.

{
    "_id" : ObjectId("5900a5797c1d501d6471d2aa"),
    "salt" : "salt key goes here",
    "hash" : "HASH key goes here",
    "username" : "theodosios86",
    "admin" : false,
    "lastname" : "Tziomakas",
    "firstname" : "Theo",
    "__v" : 0
}
{
    "_id" : ObjectId("5900a58f7c1d501d6471d2ab"),
    "salt" : "salt key goes here",
    "hash" : "HASH key goes here",
    "username" : "admin",
    "admin" : true,
    "lastname" : "admin",
    "firstname" : "admin",
    "__v" : 0

}

After logging in I get a successful json response.

{"status":"Login successful!","success":true,"token":"Token goes here"}

So he can have access to all the server's resources. However when he logs out,the token is not invalidated.

This is my code of the users model.

        var express = require('express');
        var router = express.Router();
        var passport = require('passport');
        var User = require('../models/user');
        var userRouter = express.Router();
        var Verify = require('./verify');


        router.route('/')
            .get(Verify.verifyAdmin, function (req, res, next) {
                User.find({}, function (err, users) {
                    if (err) {
                        return next(err);
                    }
                    res.json(users);
                })
            });

        router.post('/register', function(req, res) {
            User.register(new User({ username : req.body.username }),
                req.body.password, function(err, user) {
                if (err) {
                    return res.status(500).json({err: err});
                }
                        if(req.body.firstname) {
                    user.firstname = req.body.firstname;
                }
                if(req.body.lastname) {
                    user.lastname = req.body.lastname;
                }
                        user.save(function(err,user) {
                    passport.authenticate('local')(req, res, function () {
                        return res.status(200).json({status: 'Registration Successful!'});
                    });
                });
            });
        });

        router.post('/login', function (req, res, next) {
            passport.authenticate('local', function (err, user, info) {
                if (err) {
                    return next(err);
                }
                if (!user) {
                    return res.status(401).json({
                        err: info
                    });
                }
                req.logIn(user, function (err) {
                    if (err) {
                        return res.status(500).json({
                            err: 'Could not log in user'
                        });
                    }

                    var token = Verify.getToken(user);
                    res.status(200).json({
                        status: 'Login successful!',
                        success: true,
                        token: token
                    });
                });
            })(req, res, next);
        });

        router.get('/logout', function (req, res) {
            req.logout();
            res.status(200).json({
                status: 'Bye!'
            });
        });

        module.exports = router;

As you can see the get/logout route just gives me a "Bye" response,and doesn't kill the jwt.

router.get('/logout', function (req, res) {
            req.logout();
            res.status(200).json({
                status: 'Bye!'
            });
        });

And finally this is how I am verifying an ordinary and an admin user.

                    exports.getToken = function (user) {
                    return jwt.sign(user, config.secretKey, {
                        expiresIn: 3600
                    });
                };

                exports.verifyOrdinaryUser = function (req, res, next) {
                    // check header or url parameters or post parameters for token
                    var token = req.body.token || req.query.token || req.headers['x-access-token'];

                    // decode token
                    if (token) {
                        // verifies secret and checks exp
                        jwt.verify(token, config.secretKey, function (err, decoded) {
                            if (err) {
                                var err = new Error('You are not authenticated!');
                                err.status = 401;
                                return next(err);
                            } else {
                                // if everything is good, save to request for use in other routes
                                req.decoded = decoded;
                                next();
                            }
                        });
                    } else {
                        // if there is no token
                        // return an error
                        var err = new Error('No token provided!');
                        err.status = 403;
                        return next(err);
                    }
                };

                exports.verifyAdmin = function (req, res, next) {
                    // check header or url parameters or post parameters for token
                    var token = req.body.token || req.query.token || req.headers['x-access-token'];

                    // decode token
                    if (token) {
                        // verifies secret and checks exp
                        jwt.verify(token, config.secretKey, function (err, decoded) {
                            if (err) {
                                var err = new Error('You are not authenticated!');
                                err.status = 401;
                                return next(err);
                            } else {
                                // if everything is good, save to request for use in other routes
                                req.decoded = decoded;

                                if (req.decoded._doc.admin){
                                    next();
                                }else{
                                    var err = new Error('You are not authorized to perform this operation!');
                                    err.status = 403;
                                    return next(err);
                                }
                            }

                        });
                    } else {
                        // if there is no token
                        // return an error
                        var err = new Error('No token provided!');
                        err.status = 403;
                        return next(err);
                    }
                };

Any ideas?

Thanks,

Theo.



via Theo

No comments:

Post a Comment