Горячий установить аутентификацию в Passport-JWT с другой ролью пользователя? - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь добавить роль с именем admin для аутентификации администраторов, вошедших в веб-приложение панели мониторинга, в то время как обычный пользователь может просто получить доступ к обычным страницам.

Для обычного пользователя мне требуется паспорт в server.js like

// use passport 
app.use(passport.initialize());
require("./config/passport")(passport);

В config/passport.js, как и в коде официального примера, я пытаюсь это сделать:

const JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model("users");
const key  =require("../config/key");

const  opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = key.secretKey;

module.exports = passport => {
    passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
        // console.log(jwt_payload);
        User.findById(jwt_payload.id)
            .then(user => {
                if(user) {
                    return done(null, user);
                }

                return done(null, false);
            })
            .catch(err => console.log(err));
    }));
};

Этот способ отлично работает, и я использую их в маршруте

router.get("/current", passport.authenticate("jwt", {session: false}), (req, res) => {
    res.json({
        id: req.user.id,
        name: req.user.name,
        username: req.user.username,
        email: req.user.email,
        avatar: req.user.avatar,
    });
}) 

Однако, пока я добавляю роль в правило токена:

const rule = {id:admin.id, email: admin.email, avatar: admin.avatar, admin: admin.admin};

Как проверить, является ли свойство admin истинным для запроса различных коллекций в passport.js

Я попробовал это, но у меня не работает с ошибкой, похоже, сервер запускается дважды:

module.exports = passport => {
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
    // console.log(jwt_payload);
    if(jwt_payload.admin){
        Admin.findById(jwt_payload.id)
        .then(user => {
            if(user) {
                return done(null, user);
            }

            return done(null, false);
        })
        .catch(err => console.log(err));
    } else {
    User.findById(jwt_payload.id)
        .then(user => {
            if(user) {
                return done(null, user);
            }

            return done(null, false);
        })
        .catch(err => console.log(err));
    }
}));};

Ошибка: Ошибка

1 Ответ

0 голосов
/ 28 ноября 2018

Вот что я делаю, и это работает довольно хорошо ... Я просто включаю isAdmin: Boolean в свою пользовательскую модель следующим образом:

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minlength: 5,
    maxlength: 50
  },
  email: {
    type: String,
    required: true,
    minlength: 5,
    maxlength: 255,
    unique: true
  },
  password: {
    type: String,
    required: true,
    minlength: 5,
    maxlength: 1024
  },
  isAdmin: Boolean
});

, а затем включаю это в jwt следующим образом:

userSchema.methods.generateAuthToken = function() { 
  const token = jwt.sign({ _id: this._id, isAdmin: this.isAdmin }, config.get('jwtPrivateKey'));
  return token;
}

затем пользовательское промежуточное ПО для проверки значения isAdmin следующим образом:

module.exports = function (req, res, next) { 
  if (!req.user.isAdmin) return res.status(403).send('Access denied.');
  next();
}

затем я просто импортирую его и использую в качестве второго параметра для любого маршрута, например:

router.patch('/:id', [auth, isAdmin, validateObjectId], async (req, res) => {
  // handle the route (in order to do anything in this route you would need be an admin...)
});

РЕДАКТИРОВАТЬ: Если вам интересно узнать о двух других промежуточных программах здесь, они ...

auth.js:

const jwt = require('jsonwebtoken');
const config = require('config');

module.exports = function (req, res, next) {
  const token = req.header('x-auth-token');
  if (!token) return res.status(401).send('Access denied. No token provided.');

  try {
    const decoded = jwt.verify(token, config.get('jwtPrivateKey'));
    req.user = decoded; 
    next();
  }
  catch (ex) {
    res.status(400).send('Invalid token.');
  }
}

validateObjectId:

const mongoose = require('mongoose');

module.exports = function(req, res, next) {
  if (!mongoose.Types.ObjectId.isValid(req.params.id))
    return res.status(404).send('Invalid ID.');

  next();
}
...