简体   繁体   中英

How can I make my code to generate JWT token for user authorization and permission?

I am at lost as to how to make this work. I have two files, permissionCtrl.js and tokenCtrl.js . I am using nJWT , Node.js/Express.js, Sequelize & Postgres.

The Permission file contain a hasPermission function that link to the Token file. The hasPermission function is supposed to check the token generated in the token file and returns either result of success callback, or 403 response w/ messages shown below. When successful, it will grant the user access to secure route based on their role and access level. Note that tokenCtrl.hasPermission.js is imported to this file.

hasPermission.js

exports.hasPermission = (req, res, permission, success) => {
  const token = req.get('Authorization');
  const hasPermission = tokenCtrl.hasPermission(token, permission); //tokenCtrl.hasPermission not a function error here
  console.log('permission', permission);
  if (hasPermission) {
    return success();
  } else {
    res.status(403);
    return res.json({
      error: {
        status: 403,
        message: 'Unauthorized',
      },
    });
  }
};

tokenCtrl.js

const nJwt = require('njwt');
const secureRandom = require('secure-random');
const signingKey = secureRandom(512, {type: 'Buffer'}); // Create a highly random byte array of 256 bytes
const base64SigningKey = signingKey.toString('base64');

const claims = {
  iss: "mysite.com",  // The URL of your service
  sub: "users/user1234",    // The UID of the user in your system
  scope: "user, admins"
};

module.exports = {

  // Returns token
  getToken: (claims, signingKey) => {
    const jwt = nJwt.create(claims, signingKey, 'HS512');
    console.log(jwt);
    const token = jwt.compact();
     console.log("Token :" + token);
    return (token);
},

  // Returns result of token validation
    validateToken: (token, signingKey) => {
      nJwt.verify(token, signingKey, 'HS512', function(err, verifiedJwt){
        if(err){
          console.log(err); // Token has expired, has been tampered with, etc
        }else{
          console.log(verifiedJwt); // Will contain the header and body
        }
        return (verifiedJwt);
      });
  },

  token_post: (req, res) => {
  res.send(this.validateToken(req.header.Authorization, signingKey));
},

getSecret: () => {
  const secret = require('../config/secret.json').secret;
  console.log('secret', secret);
  return secret;
},

hasPermission: (token, resource) => {
  const result = this.validateToken(token, signingKey); //this.validateToken not a function error here
  console.log(result);
  if (result.name === 'JsonWebTokenError') {
    return false;
  } else if (result.permissions) {
    let permissionSet = new Set(result.permissions);
    console.log('permissions in token', JSON.stringify(permissionSet));
    return permissionSet.has(resource);
  } else {
    return false;
  }
}

}

ERRORS

  1. this.validateToken not a function error here as shown in the code comment

  2. tokenCtrl.hasPermission not a function error here as shown in the code comment

NOTE: The getSecret function in the tokenCtrl file is being used by other files.

You're running afoul of how this is bound in arrow functions. Previously functions created a new empty this in their inner scope, in arrow functions this is bound to the enclosing scope. Because you are declaring the function inside the exports object you may be expecting this to bind to the enclosing object but no.

I suggest simply declare your functions then add them to your exports afterwards. That way you can avoid the use of this and simply call your validateToken function.

const validateToken = (token, signingKey) => {
      nJwt.verify(token, signingKey, 'HS512', function(err, verifiedJwt){
        if(err){
          console.log(err); // Token has expired, has been tampered with, etc
        }else{
          console.log(verifiedJwt); // Will contain the header and body
        }
        return (verifiedJwt);
      });
  };

const hasPermission = (token, resource) => {
  const result = validateToken(token, signingKey); //this.validateToken not a function error here
  console.log(result);
  if (result.name === 'JsonWebTokenError') {
    return false;
  } else if (result.permissions) {
    let permissionSet = new Set(result.permissions);
    console.log('permissions in token', JSON.stringify(permissionSet));
    return permissionSet.has(resource);
  } else {
    return false;
  }
};

module.exports = {
  vaildiateToken,
  hasPermission
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM