Hrvatski

Istražite Next.js middleware, moćnu značajku za presretanje i izmjenu dolaznih zahtjeva. Naučite kako implementirati autentifikaciju, autorizaciju, preusmjeravanje i A/B testiranje s praktičnim primjerima.

Next.js Middleware: Ovladavanje presretanjem zahtjeva za dinamičke aplikacije

Next.js middleware pruža fleksibilan i moćan način za presretanje i izmjenu dolaznih zahtjeva prije nego što stignu do vaših ruta. Ova mogućnost omogućuje vam implementaciju širokog spektra značajki, od autentifikacije i autorizacije do preusmjeravanja i A/B testiranja, sve uz optimizaciju performansi. Ovaj sveobuhvatni vodič provest će vas kroz osnovne koncepte Next.js middlewarea i pokazati kako ga učinkovito iskoristiti.

Što je Next.js Middleware?

Middleware u Next.js-u je funkcija koja se izvršava prije nego što se zahtjev dovrši. Omogućuje vam da:

Middleware funkcije definiraju se u datoteci middleware.ts (ili middleware.js) u korijenu vašeg projekta. Izvršavaju se za svaku rutu unutar vaše aplikacije ili za određene rute na temelju konfigurabilnih uparivača (matchers).

Ključni koncepti i prednosti

Objekt 'request'

Objekt request pruža pristup informacijama o dolaznom zahtjevu, uključujući:

Objekt 'Response'

Middleware funkcije vraćaju objekt Response kako bi kontrolirale ishod zahtjeva. Možete koristiti sljedeće odgovore:

Uparivači (Matchers)

Uparivači vam omogućuju da odredite na koje rute treba primijeniti vaš middleware. Možete definirati uparivače koristeći regularne izraze ili uzorke putanja. To osigurava da se vaš middleware izvršava samo kada je potrebno, poboljšavajući performanse i smanjujući opterećenje.

Edge Runtime

Next.js middleware radi na Edge Runtimeu, što je lagano JavaScript okruženje za izvršavanje koje se može postaviti blizu vaših korisnika. Ova blizina smanjuje latenciju i poboljšava ukupne performanse vaše aplikacije, posebno za globalno distribuirane korisnike. Edge Runtime dostupan je na Vercelovoj Edge mreži i drugim kompatibilnim platformama. Edge Runtime ima neka ograničenja, posebno u korištenju Node.js API-ja.

Praktični primjeri: Implementacija značajki middlewarea

1. Autentifikacija

Autentifikacijski middleware može se koristiti za zaštitu ruta koje zahtijevaju da korisnici budu prijavljeni. Evo primjera kako implementirati autentifikaciju pomoću kolačića:


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth_token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/dashboard/:path*'],
}

Ovaj middleware provjerava prisutnost kolačića auth_token. Ako kolačić nije pronađen, korisnik se preusmjerava na stranicu /login. config.matcher specificira da se ovaj middleware treba izvršavati samo za rute pod /dashboard.

Globalna perspektiva: Prilagodite logiku autentifikacije kako biste podržali različite metode autentifikacije (npr. OAuth, JWT) i integrirali se s različitim pružateljima identiteta (npr. Google, Facebook, Azure AD) kako biste zadovoljili korisnike iz različitih regija.

2. Autorizacija

Autorizacijski middleware može se koristiti za kontrolu pristupa resursima na temelju korisničkih uloga ili dozvola. Na primjer, mogli biste imati administratorsku nadzornu ploču kojoj mogu pristupiti samo određeni korisnici.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 const token = request.cookies.get('auth_token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 // Primjer: Dohvatite korisničke uloge s API-ja (zamijenite svojom stvarnom logikom)
 const userResponse = await fetch('https://api.example.com/userinfo', {
 headers: {
 Authorization: `Bearer ${token}`,
 },
 });
 const userData = await userResponse.json();

 if (userData.role !== 'admin') {
 return NextResponse.redirect(new URL('/unauthorized', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/admin/:path*'],
}

Ovaj middleware dohvaća korisničku ulogu i provjerava ima li korisnik ulogu admin. Ako nema, preusmjerava se na stranicu /unauthorized. Ovaj primjer koristi zamjensku API krajnju točku. Zamijenite `https://api.example.com/userinfo` sa stvarnom krajnjom točkom vašeg autentifikacijskog poslužitelja.

Globalna perspektiva: Budite svjesni propisa o privatnosti podataka (npr. GDPR, CCPA) prilikom rukovanja korisničkim podacima. Implementirajte odgovarajuće sigurnosne mjere za zaštitu osjetljivih informacija i osigurajte sukladnost s lokalnim zakonima.

3. Preusmjeravanje

Middleware za preusmjeravanje može se koristiti za preusmjeravanje korisnika na temelju njihove lokacije, jezika ili drugih kriterija. Na primjer, možete preusmjeriti korisnike na lokaliziranu verziju vaše web stranice na temelju njihove IP adrese.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const country = request.geo?.country || 'US'; // Vratite se na US ako geolokacija ne uspije

 if (country === 'DE') {
 return NextResponse.redirect(new URL('/de', request.url))
 }

 if (country === 'FR') {
 return NextResponse.redirect(new URL('/fr', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/'],
}

Ovaj middleware provjerava zemlju korisnika na temelju njegove IP adrese i preusmjerava ga na odgovarajuću lokaliziranu verziju web stranice (/de za Njemačku, /fr za Francusku). Ako geolokacija ne uspije, zadana je američka verzija. Imajte na umu da ovo ovisi o dostupnosti svojstva `geo` (npr. prilikom implementacije na Vercelu).

Globalna perspektiva: Osigurajte da vaša web stranica podržava više jezika i valuta. Pružite korisnicima mogućnost ručnog odabira željenog jezika ili regije. Koristite odgovarajuće formate datuma i vremena za svaku lokaciju.

4. A/B testiranje

Middleware se može koristiti za implementaciju A/B testiranja nasumičnim dodjeljivanjem korisnika različitim varijantama stranice i praćenjem njihovog ponašanja. Evo pojednostavljenog primjera:


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

function getRandomVariant() {
 return Math.random() < 0.5 ? 'A' : 'B';
}

export function middleware(request: NextRequest) {
 let variant = request.cookies.get('variant')?.value;

 if (!variant) {
 variant = getRandomVariant();
 const response = NextResponse.next();
 response.cookies.set('variant', variant);
 return response;
 }

 if (variant === 'B') {
 return NextResponse.rewrite(new URL('/variant-b', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/'],
}

Ovaj middleware dodjeljuje korisnike ili varijanti 'A' ili 'B'. Ako korisnik već nema kolačić variant, jedan se nasumično dodjeljuje i postavlja. Korisnici dodijeljeni varijanti 'B' prepisuju se na stranicu /variant-b. Zatim biste pratili performanse svake varijante kako biste utvrdili koja je učinkovitija.

Globalna perspektiva: Uzmite u obzir kulturne razlike prilikom dizajniranja A/B testova. Ono što dobro funkcionira u jednoj regiji možda neće imati odjeka kod korisnika u drugoj. Osigurajte da je vaša platforma za A/B testiranje u skladu s propisima o privatnosti u različitim regijama.

5. Zastavice značajki (Feature Flags)

Zastavice značajki omogućuju vam da omogućite ili onemogućite značajke u svojoj aplikaciji bez implementacije novog koda. Middleware se može koristiti za utvrđivanje treba li korisnik imati pristup određenoj značajci na temelju njegovog ID-a, lokacije ili drugih kriterija.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 // Primjer: Dohvatite zastavice značajki s API-ja
 const featureFlagsResponse = await fetch('https://api.example.com/featureflags', {
 headers: {
 'X-User-Id': 'user123',
 },
 });
 const featureFlags = await featureFlagsResponse.json();

 if (featureFlags.new_feature_enabled) {
 // Omogući novu značajku
 return NextResponse.next();
 } else {
 // Onemogući novu značajku (npr. preusmjeri na alternativnu stranicu)
 return NextResponse.redirect(new URL('/alternative-page', request.url));
 }
}

export const config = {
 matcher: ['/new-feature'],
}

Ovaj middleware dohvaća zastavice značajki s API-ja i provjerava je li postavljena zastavica new_feature_enabled. Ako jest, korisnik može pristupiti stranici /new-feature. U suprotnom, preusmjerava se na /alternative-page.

Globalna perspektiva: Koristite zastavice značajki za postupno uvođenje novih značajki korisnicima u različitim regijama. To vam omogućuje praćenje performansi i rješavanje bilo kakvih problema prije puštanja značajke široj publici. Također, osigurajte da se vaš sustav zastavica značajki globalno skalira i pruža dosljedne rezultate bez obzira na lokaciju korisnika. Uzmite u obzir regionalna regulatorna ograničenja za uvođenje značajki.

Napredne tehnike

Ulančavanje middlewarea

Možete ulančati više middleware funkcija kako biste izvršili niz operacija na zahtjevu. To može biti korisno za razbijanje složene logike na manje, lakše upravljive module.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const response = NextResponse.next();

 // Prva middleware funkcija
 const token = request.cookies.get('auth_token');
 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 // Druga middleware funkcija
 response.headers.set('x-middleware-custom', 'value');

 return response;
}

export const config = {
 matcher: ['/dashboard/:path*'],
}

Ovaj primjer prikazuje dva middlewarea u jednom. Prvi obavlja autentifikaciju, a drugi postavlja prilagođeno zaglavlje.

Korištenje varijabli okruženja

Pohranjujte osjetljive informacije, poput API ključeva i vjerodajnica za bazu podataka, u varijablama okruženja umjesto da ih tvrdo kodirate u svojim middleware funkcijama. To poboljšava sigurnost i olakšava upravljanje konfiguracijom vaše aplikacije.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const API_KEY = process.env.API_KEY;

export async function middleware(request: NextRequest) {
 const response = await fetch('https://api.example.com/data', {
 headers: {
 'X-API-Key': API_KEY,
 },
 });

 // ...
}

export const config = {
 matcher: ['/data'],
}

U ovom primjeru, API_KEY se dohvaća iz varijable okruženja.

Obrada grešaka

Implementirajte robusnu obradu grešaka u svojim middleware funkcijama kako biste spriječili da neočekivane greške sruše vašu aplikaciju. Koristite try...catch blokove za hvatanje iznimaka i odgovarajuće bilježenje grešaka.


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 try {
 const response = await fetch('https://api.example.com/data');
 // ...
 } catch (error) {
 console.error('Error fetching data:', error);
 return NextResponse.error(); // Ili preusmjerite na stranicu s greškom
 }
}

export const config = {
 matcher: ['/data'],
}

Najbolje prakse

Rješavanje uobičajenih problema

Zaključak

Next.js middleware je moćan alat za izradu dinamičnih i personaliziranih web aplikacija. Ovladavanjem presretanjem zahtjeva možete implementirati širok spektar značajki, od autentifikacije i autorizacije do preusmjeravanja i A/B testiranja. Slijedeći najbolje prakse navedene u ovom vodiču, možete iskoristiti Next.js middleware za stvaranje visokoučinkovitih, sigurnih i skalabilnih aplikacija koje zadovoljavaju potrebe vaše globalne korisničke baze. Prihvatite moć middlewarea kako biste otključali nove mogućnosti u svojim Next.js projektima i pružili izvanredna korisnička iskustva.

Next.js Middleware: Ovladavanje presretanjem zahtjeva za dinamičke aplikacije | MLOG