mikenicholson / passport-jwt

Passport authentication using JSON Web Tokens
MIT License
1.96k stars 213 forks source link

Might access to other data of user #100

Closed rusmichal closed 7 years ago

rusmichal commented 7 years ago

Hello,

I noticed one behavior. I have User model in my API. It looks like that:

User.js

module.exports = function(sequelize, DataTypes) {
  var user = sequelize.define('user', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4
    },
    name: {
      type: DataTypes.STRING,
      allowNull: true
    },
    email: {
      type: DataTypes.STRING,
      unique: true,
      allowNull: false,
      validate: {
        isEmail: true,
        notEmpty: true,
        len: [1,255]
      }
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notEmpty: true
      }
    },
    password_confirmation: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notEmpty: true
      }
    },
    token: {
      type: DataTypes.STRING,
      allowNull: false,
    }
  }, {
    tableName: 'user',
    underscored: true,
    hooks: {
        beforeCreate: beforeCreateUser,
        beforeUpdate: beforeUpdateUser
      },
    classMethods:{
      associate:function(models){

      }
    },
    instanceMethods: {
      authenticate: function(value) {
        //comment code
      },
    }
  });

  return user;
};

What is important is a token property. I generate everytime new token during creating a new User. So each user has particular token (UUID) format. I use the token to authorization with passport strategy and I get access to API methods with those tokens.

I wonder. Because I have method with path parameter for example:

router.get('/:id', passport.authenticate(['jwt', 'jwt-1'], { session: false}), function(req, res, next) {
    appRepo.findById(req.params.id).then(application => {
        res.status(201).send(application)
    }).catch(error => { next(error)});
});

I have to put user token into header with Authorization key and all works fine. But I can retrive data about other users using only one token. I would like to know that. "Hey men you are using token which doesn't match to user that you are requesting". In other words I want to know that user with a specific token shouldn't have access to other data of API.

How to get this?

mikenicholson commented 7 years ago

I think you're mixing up the difference between authentication and authorization. Authentication validates a set of credentials to ensure the submitter is who they say they are. Authorization determines whether a user can perform a particular action - viewing the details of a particular user ID for example.

Passport, and by extension this passport module, is an authentication framework. It is not responsible for authorizing users, only authenticating them. You need to look into either rolling your own authorization framework or find one that someone else has written.

For a very simple example of how to add an authorization step check this out: https://github.com/expressjs/express/blob/master/examples/route-middleware/index.js. Specifically line 76.

rusmichal commented 7 years ago

Yes this is what I need.

function andRestrictToSelf(req, res, next) {
  // If our authenticated user is the user we are viewing
  // then everything is fine :)
  if (req.authenticatedUser.id == req.user.id) {
    next();
  } else {
    // You may want to implement specific exceptions
    // such as UnauthorizedError or similar so that you
    // can handle these can be special-cased in an error handler
    // (view ./examples/pages for this)
    next(new Error('Unauthorized'));
  }
}

Do you use some external libraries?

codesinghanoop commented 6 years ago

@rusmichal Did you find any solution for this ?