14

我正在尝试合并 express-jwt 库,但我不太了解它的错误处理是如何工作的。

文档说:

错误处理

默认行为是在令牌无效时抛出错误,因此您可以 > 添加自定义逻辑来管理未经授权的访问,如下所示:

    app.use(function (err, req, res, next) {
      if (err.name === 'UnauthorizedError') {
        res.status(401).send('invalid token...');
      }
    });

但我很困惑这是如何工作的。如果我有一个简单的情况,如果令牌有效,req res我想调用,或者如果不是,则调用错误,我在哪里放置该函数?nextnextapp.use

例如,这是我的代码:

router.post('/', expressJwt({  
  secret: jwtSecret,     
  credentialsRequired: false  
}), (req, res, next) => {   
  databaseController.findUser(req.user.email, (err, user) => {          
    if (err) {          
      return next(err)      
    }                        
    res.json(user)     
  })         
})

这里err将来自我的数据库调用,而不是来自 express-jwt 验证。任何帮助表示赞赏。

4

4 回答 4

40

另一种方法是,您可以将中间件与 app.use 放在一起,以扫描所有路由以在标头或查询字符串中找到有效的 jwt。使用 unless 关键字可以免除任何公共端点。前任:

app.use(expressjwt({credentialsRequired: true, secret: config.TOKEN_SECRET, requestProperty: 'user'}).unless({path: config.PUBLIC_URLs}));

app.use(function(err, req, res, next) {
    if(err.name === 'UnauthorizedError') {
      res.status(err.status).send({message:err.message});
      logger.error(err);
      return;
    }
 next();
});
于 2017-04-03T07:23:41.590 回答
8

这是我对个别路线的解决方案。

function UseJwt(){
    return [
        jwtExpress({ secret: configuration.jwtSecret, algorithms: ['HS256'] }),
        function(err, req, res, next){
            res.status(err.status).json(err);
        }
    ]
}

用法...

app.get(`/${prefix}/:user_id`,
        ...UseJwt(),
        async function (req, res) {           
           // handle your code here.
        }
)
于 2020-08-18T03:49:55.023 回答
1

您可以在用于启动 express 服务器的代码之前创建一个 express 中间件。

// Global error handler that takes 4 arguments and ExpressJS knows that
app.use((err, req, res, next) => {
    res.status(err.status).json(err);
});
app.listen(3000);

我将它用于使用 REST 的应用程序,但您可以使用相同的方法并根据您的需要修改应该发生的事情。例如,如果您使用 Jade 模板,那么您需要使用要向最终用户显示的数据填充模板并将其余部分记录在您的日志文件中。

app.use((err, req, res, next) => {
    res.locals.status = status;
    res.render('error')
});
于 2020-07-09T21:15:58.063 回答
-1
import { Schema, model } from "mongoose";

export const ROLES = ["Admin", "Estudiante","Docente","Secretario","Vicerrector","Inpector"];

const roleSchema = new Schema(
  {
    name: String,
  },
  {
    versionKey: false,
  }
);

export default model("Role", roleSchema);


//
import { Schema, model } from "mongoose";
import bcrypt from "bcryptjs";

const productSchema = new Schema(
  {
    username: {
      type: String,
      unique: true,
    },
    email: {
      type: String,
      unique: true,
    },
    password: {
      type: String,
      required: true,
    },
    //********************************NUEVOS CAMPOS PARA USUARIOS ADMINISTRADORES
    nombres: {
      type: String,
      required: true,
    },
    apellidos: {
      type: String,
      required: true,
    },
    cedula: {
      type: String,
      unique: true,
    },
    foto: {
      type: String,
      required: true,
    },
    status: {
      type: String,
      required: true,
    },
    telefono: {
      type: String,
      required: true,
    },
    //---------------TIPO DE DOCUMENTOS
    typo:{
      type: String,
    },
    //---------------TIPO MAS DATOS
    roles: [
      {
        type: Schema.Types.ObjectId,
        ref: "Role",
      },
    ],
  },
  {
    timestamps: true,
    versionKey: false,
  }
);

productSchema.statics.encryptPassword = async (password) => {
  const salt = await bcrypt.genSalt(10);
  return await bcrypt.hash(password, salt);
};

productSchema.statics.comparePassword = async (password, receivedPassword) => {
  return await bcrypt.compare(password, receivedPassword)
}

export default model("User", productSchema);

//
import Role from "../models/Role";
import User from "../models/User";

import bcrypt from "bcryptjs";

export const createRoles = async () => {
  try {
    // Count Documents
    const count = await Role.estimatedDocumentCount();

    // check for existing roles
    if (count > 0) return;

    // Create default Roles
    const values = await Promise.all([
      new Role({ name: "Estudiante" }).save(),//user
      new Role({ name: "Docente" }).save(),//moderator
      new Role({ name: "Admin" }).save(),//admin
      new Role({ name: "Secretario" }).save(),//-------+++
      new Role({ name: "Vicerrector" }).save(),//-------+++
      new Role({ name: "Inpector" }).save(),//-------+++
    ]);

    console.log(values);
  } catch (error) {
    console.error(error);
  }
};

export const createAdmin = async () => {
  // check for an existing admin user
  const user = await User.findOne({ email: "10004095632w@gmailcom" });
  // get roles _id
  const roles = await Role.find({ name: { $in: ["Admin", "Estudiante","Docente","Secretario","Vicerrector","Inpector"] } });

  if (!user) {
    // create a new admin user
    await User.create({
      username: "admin",
      email: "10004095632w@gmail.com",
      password: await bcrypt.hash("Imperio 789.", 10),
      roles: roles.map((role) => role._id),
      nombres: "ad",
      apellidos: "ad",
      cedula: "123456789",
      foto: "profile.jpg",
      status: "Activo",
      telefono: "+570995283857",
    });
    console.log('Admin User Created!')
  }
};

//
import jwt from "jsonwebtoken";
import config from "../config";
import User from "../models/User";
import Role from "../models/Role";

export const verifyToken = async (req, res, next) => {
  let token = req.headers["x-access-token"];

  if (!token) return res.status(403).json({ message: "No token provided" });

  try {
    const decoded = jwt.verify(token, config.SECRET);
    req.userId = decoded.id;

    const user = await User.findById(req.userId, { password: 0 });
    if (!user) return res.status(404).json({ message: "No user found" });

    next();
  } catch (error) {
    return res.status(401).json({ message: "Unauthorized!" });
  }
};

export const isSecretario = async (req, res, next) => {
  try {
    const user = await User.findById(req.userId);
    const roles = await Role.find({ _id: { $in: user.roles } });

    for (let i = 0; i < roles.length; i++) {
      if (roles[i].name === "Secretario") {
        next();
        return;
      }
    }

    return res.status(403).json({ message: "Require Moderator Role!" });
  } catch (error) {
    console.log(error)
    return res.status(500).send({ message: error });
  }
};

export const isAdmin = async (req, res, next) => {
  try {
    const user = await User.findById(req.userId);
    const roles = await Role.find({ _id: { $in: user.roles } });

    for (let i = 0; i < roles.length; i++) {
      if (roles[i].name === "Admin"||roles[i].name === "Secretario") {
        next();
        return;
      }
    }

    return res.status(403).json({ message: "Require Admin Role!" });
  } catch (error) {
    console.log(error)
    return res.status(500).send({ message: error });
  }
};

//

import User from "../models/User";
import { ROLES } from "../models/Role";

const checkDuplicateUsernameOrEmail = async (req, res, next) => {
  try {
    const user = await User.findOne({ username: req.body.username });
    if (user)
      return res.status(400).json({ message: "El numero de cédula ya existe" });
    const email = await User.findOne({ email: req.body.email });
    if (email)
      return res.status(400).json({ message: "El correo electrónico ya existe" });
    next();
  } catch (error) {
    res.status(500).json({ message: error });
  }
};

const checkRolesExisted = (req, res, next) => {
  if (req.body.roles) {
    for (let i = 0; i < req.body.roles.length; i++) {
      if (!ROLES.includes(req.body.roles[i])) {
        return res.status(400).json({
          message: `Role ${req.body.roles[i]} does not exist`,
        });
      }
    }
  }

  next();
};

export { checkDuplicateUsernameOrEmail, checkRolesExisted };

//
import * as authJwt from "./authJwt";
import * as verifySignup from "./verifySignup";

export { authJwt, verifySignup };
于 2021-08-06T12:01:35.743 回答