基于多部分/表单数据参数的Multer权限(ACL)中间件

时间:2018-01-12 21:00:46

标签: node.js express file-upload authorization multer

在我的Express.js REST API中,我使用 multer 将图片上传到服务器的diskStorage静态文件夹中。我想为用户和管理员构建通用文件上传页面。具体用例如下:

  • 从下拉列表中选择category
  • 在表单字段
  • 中写一个有效的id
  • 选择有效的image(file)并提交。
  • 如果普通用户(isAdmin==false)选择的categoryusers不同,则API会以403响应,并且根本不会上传图片。

我想要实现的是仅允许isAdmin==true的用户上传所有类别的图片。但是,在同一路线中,普通用户只能上传users类别的图片。

问题是如何访问req.body.category内部身份验证&授权中间件和拒绝上传前的过程?

我需要同时检查categoryisAdmin字段,以决定是否允许上传过程。

阵营侧

const formData = new FormData()

formData.append('id', this.state.id)
formData.append('category', this.state.category)
formData.append('photo', this.state.file)

this.props.fileUpload(formData)

快递侧

路由器

router.post('/upload', AuthController.role('admin'), UploadController.uploadPhoto);

AuthController

public static role(role: any) {
  return (req: Request, res: Response, next: NextFunction) => {
    if (role === 'admin') {
      console.dir(req.body); // req.body prints { user_id: 1, isAdmin: true }
    // cannot decide whether give access to the route or not over here because we don't know the req.body.category yet.
      if (req.body && req.body.isAdmin) {
        next();
      } else {
        return res.status(403).send(new Unauthorized());
      }
    }
   };
 }

UploadController

const imageFilter = (req, file, cb) => {
  console.dir(req.body); // prints { id: '1', category: 'users' } cannot access req.body.isAdmin over here
  if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
    return cb(new Error('Only image files are allowed!'), false);
  }
  cb(null, true);
};

const upload = util.promisify(multer({ storage, fileFilter: imageFilter, limits: {fileSize: MAX_SIZE} })
                                                                                  .single('photo'));
export class UploadController {
  public static async uploadPhoto(req: any, res: Response, next: NextFunction) { 
    // req.body.isAdmin is available over here    
    try {
      await upload(req, res);
      imageUrl = `${HOST}/static/${req.file.filename}`;
    } catch (e) {
      return res.status(400).send(new BadRequest('Image upload operation is not successful.'));
 }
}

更新:我当前的解决方法是临时保存图像,然后在categoryisAdmin可用的同时检查它们。

try {
     await upload(req, res);
     ....
     ..
     // Now req.body.category and req.body.isAdmin are both available here
 }

0 个答案:

没有答案