2012-09-23 11 views
6

Sto costruendo un'app express e mi piacerebbe sapere quale fantasia posso ottenere con il middleware. Approssimativamente, voglio realizzare quanto segue con il middleware.Node.js organizzazione del middleware e validazione dei parametri

Fatto:

  • Aggiungi RequestID a tutte le rotte richiesta
  • Autentica
  • controllare se un utente ha accesso a una determinata risorsa (a parte l'autenticazione )

non fatto:

  • A) parametri Convalidare per un dato percorso
  • B) Organizzare middleware in modo sano se differisce da una via, e 3 middleware sono chiamati regolarmente a tratta

Ho definito il mio middleware in un file separato, e importarlo in app.js in questo modo:

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

applicarlo a tutte le rotte lo aggiungo esprimere 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 
}); 

E per le specifiche di percorso, lo aggiungo come argomento app.get:

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

Problema Un

Mi piacerebbe avere middleware che avrei potuto utilizzare per controllare i parametri

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

e usarlo in questo modo per un determinato percorso:

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

C'è un buon modo per fare questo? O dovrei semplicemente convalidare in base alla rotta all'interno dei file di definizione del percorso?

Problema B

Esiste un modo migliore per organizzare e utilizzare il mio middleware che devo considerare?

Aggiornamento

Sto cercando un modo per convalidare i parametri che cambiano molto tra percorsi. Ovviamente il sotto non funziona, non posso passare i param nel middleware, ma è possibile che io definisca il middleware che lo fa e lo chiamo come ho detto sopra?

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(); 
} 
+0

Si vorrà passare req, res al proprio middleware in modo da validare (req, res) e quindi agire su di esso da lì. Di solito è più semplice che passare in variabili predeterminate. – Brandon

+0

Prova a cercare in express-validator. Non l'ho usato nel middleware, ma sembra possibile: https://github.com/ctavan/express-validator – chovy

risposta

2

Problema Un

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

Problema B

È possibile utilizzare il middleware in un modo che non sempre è necessario chiamare l'autenticazione e la convalida sono chiamati automaticamente. Ma questo può portare a un disastro, per esempio. Il tuo middleware sarebbe quindi in esecuzione su ogni chiamata, quindi per REGISTRAZIONE/REGISTRAZIONE non è necessario eseguire l'autenticazione.

Con la convalida, a volte è necessario convalidare l'e-mail, a volte il telefono no. quindi entrambi non possono andare d'accordo.

Quindi usarli separatamente su ogni chiamata sembra il modo migliore per me.

+0

Per A, quello che stavo cercando di convalidare diversi set di parametri per percorsi diversi - validare (x), validare (x, y), convalida (x, y, z). È possibile passare parametri come questo, o dovrei semplicemente impostare il parametro su un array e trasmetterlo come validato (req, res, desapareconsulti, next) ... – nflacco

+0

beh, sì. Ma penso che dovresti fare in modo che le funzioni SUB e passarle all'interno della funzione siano valide. Come validate_email (req.body.email); o anche validate_desired (desiderateparams), e per il percorso dovresti controllare req.params, ** PS: Ecco come lo faccio. ** :) –

+0

ok, che sembra abbastanza ragionevole – nflacco

2

È possibile utilizzare express-validation per convalidare corpo, query, parametri, intestazioni e cookie di una richiesta. Risponde con errori, se una delle regole di convalida configurate non riesce.

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

Questo controllerà se l'e-mail e la password del corpo params corrisponde alle regole di convalida.

Se la convalida fallisce, risponderà con il seguente errore.

{ 
    "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" ] 
    } 
    ] 
} 

È inoltre possibile controllare il mio repo express-mongoose-es6-rest-api per l'integrazione completa.

1

È inoltre possibile utilizzare una funzione di ordine superiore (funzione che restituisce una funzione). Con ciò passa una serie di parametri specifici dell'endpoint da controllare.

module.export = Class RequestValidator { 
    static validate(params) { 
    return function(req, res, next){ 
     for(const param of params) { 
     validateYourParams here... 
     if (validation fails) { 
     return next(new Error()); 
     } 
     } 
     next(); 
    } 
    } 
} 

E all'interno della vostra routeDefinition ora è possibile chiamare il middleware convalida e passare gli argomenti specifici di percorso ad esso.

const RequestValidator = require('your-validation-middleware'); 
const controller = require('your-controller'); 

app.post('/path') 
    .RequestValidator.validate(
    [{ 
    name: 'paramName', 
    type: 'boolean' 
    }, 
    { 
    name: 'paramName2', 
    type: 'string' 
    } 
    ]) 
    .Controller.handleRequest; 
Problemi correlati