【问题标题】:JWT Authentication & AuthorizationJWT 认证和授权
【发布时间】:2017-09-11 00:44:55
【问题描述】:

我正在尝试找到一种方法来保护每个用户资源免受其他正确授权的用户的影响。所以这是错误的流程:

如您所见,Alice 拥有正确的 JWT 令牌,并且如果她(以某种方式)设法获取 John 的 ID,她就能够获取 Johns 的信息。我想防止这种情况发生……我该怎么做?

这是我用于护照身份验证的代码。一切正常,我只是想增加额外的安全层。

passportTest.js

'use strict';
// load environment variables
require('dotenv').config();
/**
*Module dependencies
*/

const passport = require('passport');
const User = require('../models/user');
let jwt = require('jsonwebtoken');
/**

*Configuration and Settings
*/
const utilities = require('../models/utilities');

const errHandler = utilities.errHandler;
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const LocalStrategy = require('passport-local').Strategy;
const jwtOptions = {
  // Telling Passport to check authorization headers for JWT
  jwtFromRequest: ExtractJwt.fromAuthHeader(),
  // Telling Passport where to find the secret
  secretOrKey: process.env.SECRET
};


// Configure Passport to use JWT strategy to look up Users.
passport.use('jwt', new JwtStrategy(jwtOptions, function (jwt_payload, done) {
  User.findById({ _id: jwt_payload._doc._id }, (err, user) => {
    if (err) {
      return done(err, false);
    }

    if (user) {
      return done(null, user);
    } else {
      return done(null, false);
    }
  })
}));


passport.use('local-login', new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true
},
  function (req, email, password, done) {
    User.findOne({ email: email }, (err, user) => {
      if (err) {
        return errHandler(err);
      }

      if (!user) {
        return done(null, false, {
          errMsg: 'User does not exist, please' +
          ' <a class="errMsg" href="/signup">signup</a>'
        });
      }

      if (!user.validPassword(password)) {
        return done(null, false, { errMsg: 'Invalid password try again' });
      }

      return done(null, user);
    });

  }));
/**
*Export Module
*/
module.exports = passport;

Routes.js

'use strict';
// load environment variables
require('dotenv').config();
/**
*Module dependencies
*/
const express = require('express');
const passport = require('../config/passport');
const authChecker = require('../config/authentication-checker');
const passportTest = require('../config/passport-jwt');
let jwt = require('jsonwebtoken');
const utilities = require('../models/utilities');
const userController = require('../controllers/user.controller');
const expressJwt = require('express-jwt');

//==============================================================================
/**
*Create router instance
*/
var router = express.Router();
//==============================================================================
/**
*Module Variables
*/
//needed to protect the '/dashboard' route
function isLoggedIn(req, res, next) {
  if (req.headers.authorization) {
    passportTest.authenticate('jwt', { session: false }, (err, user) => {
      if (err) { return res.status(401); }

      if (user) {
        req.user = user;
        return next();
      } else {
        return res.status(401);
      }
    })(req, res, next);
  } else {
    return res.redirect('/login');
  }
}
//==============================================================================
/**
*Middleware
*/
router.use(passport.initialize());
router.use(passport.session());
// Authenticate the user and get a JSON Web Token to include in the header of future requests.
router.route('/auth').post((req, res, next) => {
  passportTest.authenticate('local-login', function (err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    if (!user) {
      return res.status(409).render('pages/login', { errMsg: info.errMsg });
    }
    req.login(user, function (err) {
      if (err) {
        console.error(err);
        return res.status(409);
      }
      return res.status(200).json(generateToken(user));
    });
  })(req, res, next);
}
);

// Example of required auth: protect dashboard route with JWT
router.get('/secure', isLoggedIn, function (req, res) {
  return res.send('It worked' + req.user);
});
router.route('/signup')
  .get(function (req, res) {
    return res.render('pages/signup');
  })
  .post(function (req, res, next) {
    passport.authenticate('local-signup', function (err, user, info) {
      if (err) {
        return next(err); // will generate a 500 error
      }
      if (!user) {
        return res.status(409).render('pages/signup', { errMsg: info.errMsg });
      }
      req.login(user, function (err) {
        if (err) {
          console.error(err);
          return next(err);
        }
        return res.redirect('/dashboard');
      });
    })(req, res, next);
  });
router.route('/api/users/id/:id').get(isLoggedIn, userController.getUserById)

提前致谢。

【问题讨论】:

    标签: javascript node.js authentication jwt passport.js


    【解决方案1】:

    只需将 userId 添加到 JWT 声明(有效负载)。然后你总是可以检查

    if (claim.userId !== request.params.userId) {
        res.status(403);
        return next();
    }
    

    【讨论】:

    • 谢尔盖在哪里?在用户控制器中?
    • 这项检查将在端点控制器中进行。您可以在发布 JWT 时设置 JWT 声明。请参阅密码的文档以了解其工作原理。
    • 我已经设法让它工作了。使用这种方法也可以开始使用微服务方法吗?
    • 是的! JWT 对于微服务非常有用,因为您可以在它们相互通信时对其进行身份验证。
    • Sergey Yarotskiy 很抱歉打扰您,但是在所有端点中进行此数据库验证并不过分?
    猜你喜欢
    • 2021-11-08
    • 2020-09-06
    • 1970-01-01
    • 2020-11-29
    • 2019-03-07
    • 2018-07-25
    • 2010-11-14
    • 2013-08-08
    相关资源
    最近更新 更多