如何使用Express-JWT处理错误

时间:2016-12-05 08:51:07

标签: node.js express jwt express-jwt

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

documentation说:

  

错误处理

     

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

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

但我很困惑这是如何工作的。如果我有一个简单的req res情况,并且我想在令牌有效时调用next,或者如果不是,则调用next但是如果错误则调用app.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

这里的<div ng-controller="MainCtrl"> <div id="grid1" ui-grid="gridOptions1" class="grid"></div> </div> 来自我的DB调用,而不是来自express-jwt验证。 任何帮助表示赞赏。

4 个答案:

答案 0 :(得分:15)

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

.col-lg-

答案 1 :(得分:2)

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

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.
        }
)

答案 2 :(得分:1)

您可以在用于启动Express Server的代码之前创建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')
});

答案 3 :(得分:0)

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 };
相关问题