Mongoose:将用户授权功能从控制器移动到模型

时间:2016-01-07 03:23:36

标签: node.js mongoose angular-fullstack

我对最佳做法以及如何添加用户授权功能有疑问。它应该在模型,控制器或其他地方。

目前,

我一直在我的Mongoose模型中构建验证功能

我一直在使用中间件构建身份验证/授权检查,并从我的路由调用。

我目前的挑战是,经过身份验证和授权的用户尝试更新他们不是所有者的模型。

我的经过身份验证的用户已经附加到我的请求中,但是这些数据不会从Mongoose模型中获得,因此我认为我应该在模型上创建某种验证函数,可以从我的调用控制器,以便我的逻辑与模型很好地存在,但可以从控制器调用。

enter image description here

控制器

exports.create = function (req, res) {

  try {

    if (!_.isEmpty(req.body.entity.ordererAccountId) && !_.isEqual(req.user.accountId.toString(), req.body.entity.ordererAccountId)) {
      var err = mong.formatError({ message: 'Invalid Account Access' });

      return res.status(403).json(err);
    }

    OrderSchema.create(req.body.entity, function (err, entity) {

      if (err) {
        return mong.handleError(res, err);
      }

      return res.status(201).json(mong.formatSuccess(entity));
    });

  } catch (e) {
    console.log(e);
  }
};

模型

'use strict';

// ------------------------------------------------------------
// Order Model
// ------------------------------------------------------------

var mongoose = require('mongoose');
var findOneOrCreate = require('mongoose-find-one-or-create');

var Schema = mongoose.Schema;

var OrderSchema = new Schema({
  created_at: { type: Date },
  updated_at: { type: Date },

  ordererAccountId:
    {
      type: Schema.ObjectId, ref: 'Account',
      required: true
    },
  supplierAccountId:
    {
      type: Schema.ObjectId, ref: 'Account'
    },
  userId:
    {
      type: Schema.ObjectId, ref: 'User',
      required: true
    },
  status: {
    type: String,
    enum: ['Open', 'Sent'],
    default: 'Open'
  },
  notes: String,
  supplierCompanyName: String,
  supplierEmail: String,
  supplierContactName: String,
  supplierPhone1: String,
  supplierPhone2: String,
  deliveryCompanyName: String,
  deliveryEmail: String,
  deliveryFirstName: String,
  deliveryLastName: String,
  deliveryAddress1: String,
  deliveryAddress2: String,
  deliveryCity: String,
  deliveryState: String,
  deliveryPostCode: String,
  deliveryCountry: String,
  deliveryPhone1: String,
  deliveryPhone2: String,
});

OrderSchema.plugin(findOneOrCreate);

// ------------------------------------------------------------
// Validations
// ------------------------------------------------------------

// Validate only one open order at a time per user
OrderSchema
  .path('status')
  .validate(function (status, respond) {

    var Order = mongoose.model('Order');

    // Excluding this Order, make sure there are NO other orders for this user with the status of 'Open'
    var condition = {
      userId: this.userId,
      status: 'Open',
      _id: { $ne: this._id }
    };

    Order.count(condition, function (err, count) {

      if (err) {
        console.log(err);
      }
      else {
        respond(count === 0);
      }

    });

  }, 'There can be only one open order at a time.');

// ------------------------------------------------------------
// Pre-Save Hook
// ------------------------------------------------------------

OrderSchema.pre('save', function (next) {
  var now = new Date().getTime();

  this.updated_at = now;
  if (!this.created_at) {
    this.created_at = now;
  }

  next();
});

module.exports = mongoose.model('Order', OrderSchema);

1 个答案:

答案 0 :(得分:0)

你可以使用你的"创建"通过执行以下操作,在路由器中充当验证中间件:

      app.post('/yourRoute', create, function(req, res) {
            //if validation success
            //do somthing
        });

不要忘记通过" next"作为创建功能

的第三个参数