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:
- Presrećete zahtjeve: Ispitate zaglavlja, kolačiće i URL dolaznog zahtjeva.
- Mijenjate zahtjeve: Prepišete URL-ove, postavite zaglavlja ili preusmjerite korisnike na temelju određenih kriterija.
- Izvršavate kôd: Pokrenete logiku na strani poslužitelja prije renderiranja stranice.
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:
request.url
: Puni URL zahtjeva.request.method
: HTTP metoda (npr. GET, POST).request.headers
: Objekt koji sadrži zaglavlja zahtjeva.request.cookies
: Objekt koji predstavlja kolačiće zahtjeva.request.geo
: Pruža geolokacijske podatke povezane sa zahtjevom, ako su dostupni.
Objekt 'Response'
Middleware funkcije vraćaju objekt Response
kako bi kontrolirale ishod zahtjeva. Možete koristiti sljedeće odgovore:
NextResponse.next()
: Nastavlja normalnu obradu zahtjeva, dopuštajući mu da stigne do predviđene rute.NextResponse.redirect(url)
: Preusmjerava korisnika na drugu URL adresu.NextResponse.rewrite(url)
: Prepravlja URL zahtjeva, učinkovito poslužujući drugu stranicu bez preusmjeravanja. URL u pregledniku ostaje isti.- Vraćanje prilagođenog objekta
Response
: Omogućuje vam posluživanje prilagođenog sadržaja, poput stranice s greškom ili određenog JSON odgovora.
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
- Neka middleware funkcije budu lagane: Izbjegavajte izvođenje računski intenzivnih operacija u middlewareu, jer to može utjecati na performanse. Prebacite složenu obradu na pozadinske zadatke ili namjenske servise.
- Učinkovito koristite uparivače: Primjenjujte middleware samo na rute koje ga zahtijevaju.
- Temeljito testirajte svoj middleware: Pišite jedinične testove kako biste osigurali da vaše middleware funkcije ispravno rade.
- Pratite performanse middlewarea: Koristite alate za praćenje kako biste pratili performanse svojih middleware funkcija i identificirali eventualna uska grla.
- Dokumentirajte svoj middleware: Jasno dokumentirajte svrhu i funkcionalnost svake middleware funkcije.
- Uzmite u obzir ograničenja Edge Runtimea: Budite svjesni ograničenja Edge Runtimea, kao što je nedostatak Node.js API-ja. Prilagodite svoj kôd u skladu s tim.
Rješavanje uobičajenih problema
- Middleware se ne izvršava: Dvaput provjerite konfiguraciju uparivača kako biste bili sigurni da se middleware primjenjuje na ispravne rute.
- Problemi s performansama: Identificirajte i optimizirajte spore middleware funkcije. Koristite alate za profiliranje kako biste locirali uska grla u performansama.
- Kompatibilnost s Edge Runtimeom: Osigurajte da je vaš kôd kompatibilan s Edge Runtimeom. Izbjegavajte korištenje Node.js API-ja koji nisu podržani.
- Problemi s kolačićima: Provjerite postavljaju li se i dohvaćaju li se kolačići ispravno. Obratite pozornost na atribute kolačića kao što su
domain
,path
isecure
. - Konflikti zaglavlja: Budite svjesni potencijalnih konflikata zaglavlja prilikom postavljanja prilagođenih zaglavlja u middlewareu. Osigurajte da vaša zaglavlja ne prepisuju nenamjerno postojeća zaglavlja.
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.