8

I'm building an express app and I'd like to know how fancy I can get with middleware. Roughly, I want to accomplish the following with middleware.

Done:

  • Add requestId to all routes
  • Authenticate request
  • Check whether a user has access to a given resource (apart from authentication)

Not done:

  • A) Validate parameters for a given route
  • B) Organize middleware in a sane way if it differs from route to route, and 3 middlewares are called routinely per route

I have defined my middleware in a separate file, and import it into app.js like so:

var middleware = require('./middleware');
var requestId = middleware.requestId;
var authenticate = middleware.authenticate;

To apply it to all routes I add it to express config:

var app = express.createServer();
app.configure(function () {
  app.use(express.logger());
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(requestId); // add requestId to all incoming requests
});

And for route specifics, I add it as an app.get argument:

var routes = require('./v1/routes');
app.get("/v1/foo", routes.foo);
app.get("/v1/bar", authenticate, routes.bar);

Problem A

I'd love to have middleware that I could use to check parameters

validate('x','y','z')

And use it like so for a given route:

app.get("/v1/bar", authenticate, validate('x','y','z'), routes.bar);

Is there a good way to do this? Or should I just be validating on per route basis inside the route definition files?

Problem B

Is there a better way to organize and use my middleware that I should consider?

Update

I'm looking for a way to validate parameters that change a lot between routes. The below obviously don't work- I cannot pass params into the middleware- but is there way where I can define middleware that does this and call it as I've said above?

var validateParams = function (req, res, params, callback) {
  // Make sure the required parameters are in the request
  console.log('checking for params '+params);
  for (var i = 0; i < params.length; i++) {
    var param = params[i];
    if(!(param in req.query)){
      logger.info('cannot find param ['+param+'] in req: '+JSON.stringify(req.query));
      res.writeHead(400, {
        "Content-Type": "application/json"
      });
      var out = {
        "err": "request missing required parameters"
      };
      res.end(JSON.stringify(out));
      return;      
    }
  }
  callback();
}
4

3 に答える 3

2

問題A

app.get("/v1/bar", authenticate, validate, routes.bar);

function validate(req,res,next){

//Get all parameters here by req.params and req.body.parameter
//validate them and return.
if(validation_true)
next()
}

問題B

ミドルウェアは、認証を呼び出す必要がなく、自動的に呼び出されることを検証する必要がない方法で使用できます。しかし、それは、例えば、混乱につながる可能性があります。ミドルウェアはすべての呼び出しで実行されるため、SIGNUP/REGISTERの場合は認証を実行しても意味がありません。

検証を使用すると、電子メールを検証する必要がある場合もあれば、電話番号を検証する必要がある場合もあります。ですから、両方がうまくいくことはできません。

したがって、すべての呼び出しでそれらを別々に使用することは、私にとって最良の方法のようです。

于 2012-09-23T03:00:53.447 に答える
2

Express-validationを使用して、リクエストの本文、クエリ、パラメーター、ヘッダー、および Cookie を検証できます。構成された検証ルールのいずれかが失敗した場合、エラーで応答します。

var validate = require('express-validation'),
    Joi = require('joi');

app.post('/login', validate({
  body: {
    email: Joi.string().email().required(),
    password: Joi.string().regex(/[a-zA-Z0-9]{3,30}/).required()
  }
}), function(req, res){
    res.json(200);
});

これにより、電子メールとパスワードの本文パラメーターが検証ルールと一致するかどうかがチェックされます。

検証に失敗すると、次のエラーが返されます。

{
  "status": 400,
  "statusText": "Bad Request",
  "errors": [
    {
      "field": "password",
      "location": "body",
      "messages": [
        "the value of password is not allowed to be empty",
        "the value of password must match the regular expression /[a-zA-Z0-9]{3,30}/"
      ],
      "types": [ "any.empty", "string.regex.base" ]
    }
  ]
}

完全な統合については、私のレポである express-mongoose-es6-rest-apiを確認することもできます。

于 2015-09-24T12:13:05.990 に答える