De levenscyclus van een aanvraag beheren met middleware

Voltooid

Tailwind Traders wil hun web-API beveiligen. In sommige gevallen moet u, wanneer een aanvraag een webtoepassing bereikt, het volgende controleren:

  • Verificatie: wie de gebruiker is
  • Autorisatie: wat de gebruiker mag zien of doen

Aanvraagstappen

Zie het verwerken van een aanvraag als een reeks stappen. Als de gebruiker moet zijn aangemeld om een resource te verwerken, kunnen de stappen er als volgt uitzien:

  1. Voorverwerking: een optionele stap om code uit te voeren voordat de aanvraag wordt verwerkt.

    Een voorbeeld is om te bepalen of de gebruiker de juiste referenties heeft verzonden via een aanvraagheader. Als de referenties zijn geverifieerd, verstuurt u de aanvraag naar de volgende stap. Als de logboekregistratie mislukt, retourneert de server een 401 HTTP-antwoord.

  2. Verwerken: de aanvraag verwerken, zoals met een soort gegevensbron, zoals een database of een API-eindpunt.

    Met deze stap wordt de resource geretourneerd, zolang de aanvraag op de juiste manier om de resource vraagt.

  3. Naverwerking: een optionele stap om code uit te voeren nadat de aanvraag is voltooid.

    Een voorbeeld is het vastleggen van de resultaten voor bewakingsdoeleinden.

Het Express-framework biedt ingebouwde ondersteuning voor het op deze manier verwerken van een aanvraag. Als u een voorverwerking of naverwerking voor een aanvraag wilt uitvoeren, implementeert u de use() methode in uw Express-object app met de volgende syntaxisformulier:

app.use((req, res, next) => {})

De methode die in de use() methode is doorgegeven, heeft de volgende parameters:

  • req: De binnenkomende aanvraag die aanvraagheaders en de aanroepende URL bevat. Het bevat mogelijk ook een hoofdtekst van gegevens als de client gegevens heeft verzonden bij de aanvraag.
  • res: Een antwoordstroom die moet worden gebruikt voor het schrijven van informatie, zoals headers en gegevens die u wilt terugsturen naar de aanroepende client.
  • next: De volgende middlewarefunctie in de stack. Als de next() functie niet wordt aangeroepen, stopt de verwerking van de aanvraag. Als de aanvraag is geslaagd, kunt u volgende() aanroepen om wijzigingen aan te brengen in het antwoord of de resultaten te registreren.

Aanvraagpijplijn

Als u routes hebt die profiteren van pre- of postverwerkings-middleware, stelt u de functies in het broncodebestand in, zodat:

  • Middleware die moet worden uitgevoerd voordat de aanvraag (voorverwerking) wordt gedefinieerd vóór de werkelijke aanvraag.
  • Middleware die moet worden uitgevoerd nadat de aanvraag (naverwerking) is gedefinieerd na de werkelijke aanvraag.

Bekijk dit voorbeeld:

app.use((req, res, next) => {
  // Pre request
})
app.get('/protected-resource', () => {
  // Handle the actual request
})
app.use((req, res, next) => {
  // Post request
})

app.get('/login', () => {})

U kunt ook preprocessing middleware uitvoeren als argument voor de aanvraaghandler:

app.get(
  '/<some route>',
 () => {
   // Pre request middleware
 }, () => {
   // Handle the actual request
 })

De volgorde van middlewarefuncties in Express.js is van cruciaal belang omdat ze opeenvolgend worden uitgevoerd, in de volgorde waarin ze in de code worden gedefinieerd. Dit betekent dat als een middlewarefunctie na een route-handler wordt geplaatst, deze niet wordt uitgevoerd voor die route.

Best practices voor routebeheer

Hier volgen enkele aanbevolen procedures voor het beheren van de volgorde van middlewarefuncties:

  • Plaats globale middleware bovenaan: Middleware-functies die van toepassing zijn op alle routes, moeten boven aan uw code worden geplaatst, vóór eventuele route-handlers. Dit zorgt ervoor dat ze voor elke aanvraag worden uitgevoerd.

  • Middleware rangschikt op specificiteit: Meer specifieke middlewarefuncties moeten na algemenere functies worden geplaatst. Op deze manier kunnen de algemene middlewarefuncties algemene taken voor alle routes verwerken en de specifieke functies kunnen taken voor specifieke routes verwerken.

  • Plaats de middleware voor foutafhandeling als laatste: Middleware-functies met vier argumenten worden behandeld als middleware voor foutafhandeling. Ze moeten aan het einde van uw middlewarestack worden geplaatst, na alle andere middleware- en routehandlers.

Hier volgt een voorbeeld:

const express = require('express');
const app = express();

// Global middleware
app.use((req, res, next) => {
  console.log('This is a global middleware');
  next();
});

// Route handler
app.get('/', (req, res, next) => {
  console.log('This is a route handler');
  next();
});

// Specific middleware
app.use((req, res, next) => {
  console.log('This is a specific middleware');
  next();
});

// Error-handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

app.listen(3000);