Imejte več nadzora nad logiko preverjanja pristnosti aplikacije Next.js prek izvajanja preverjanja pristnosti po meri, ki temelji na JWT.
Preverjanje pristnosti žetonov je priljubljena strategija, ki se uporablja za zaščito spletnih in mobilnih aplikacij pred nepooblaščenim dostopom. V Next.js lahko uporabite funkcije za preverjanje pristnosti, ki jih ponuja Next-auth.
Lahko pa se odločite za razvoj sistema za preverjanje pristnosti po meri na podlagi žetonov z uporabo spletnih žetonov JSON (JWT). S tem zagotovite večji nadzor nad logiko preverjanja pristnosti; v bistvu prilagajanje sistema, da natančno ustreza zahtevam vašega projekta.
Nastavite projekt Next.js
Za začetek namestite Next.js tako, da na terminalu zaženete spodnji ukaz.
npx create-next-app@latest next-auth-jwt --experimental-app
Ta vodnik bo uporabil Next.js 13, ki vključuje imenik aplikacij.
Nato namestite te odvisnosti v svoj projekt z uporabo npm, upravitelj paketov vozlišč.
npm install jose universal-cookie
Jose je modul JavaScript, ki ponuja nabor pripomočkov za delo s spletnimi žetoni JSON, medtem ko
univerzalni-piškotek odvisnost zagotavlja preprost način za delo s piškotki brskalnika v okoljih na strani odjemalca in na strani strežnika.Tukaj lahko najdete kodo tega projekta Repozitorij GitHub.
Ustvarite uporabniški vmesnik prijavnega obrazca
Odprite src/app ustvarite novo mapo in jo poimenujte Vpiši se. Znotraj te mape dodajte novo page.js datoteko in vključite spodnjo kodo.
"use client";
import { useRouter } from"next/navigation";
exportdefaultfunctionLoginPage() {
return (
Zgornja koda ustvari funkcionalno komponento prijavne strani, ki bo v brskalniku prikazala preprost obrazec za prijavo, ki uporabnikom omogoča vnos uporabniškega imena in gesla.
The uporabite odjemalca stavek v kodi zagotavlja, da je deklarirana meja med kodo samo za strežnik in samo za odjemalca v aplikacija imenik.
V tem primeru se uporablja za izjavo, da je koda na strani za prijavo, zlasti handleSubmitfunkcija se izvaja samo na odjemalcu; sicer bo Next.js vrgel napako.
Zdaj pa definirajmo kodo za handleSubmit funkcijo. Znotraj funkcionalne komponente dodajte naslednjo kodo.
const router = useRouter();
const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const username = formData.get("username");
const password = formData.get("password");
const res = await fetch("/api/login", {
method: "POST",
body: JSON.stringify({ username, password }),
});
const { success } = await res.json();
if (success) {
router.push("/protected");
router.refresh();
} else {
alert("Login failed");
}
};
Za upravljanje logike preverjanja pristnosti prijave ta funkcija zajame uporabniške poverilnice iz obrazca za prijavo. Nato končni točki API pošlje zahtevo POST, ki posreduje podatke o uporabniku za preverjanje.
Če so poverilnice veljavne, kar pomeni, da je bil postopek prijave uspešen, API vrne status uspeha v odgovoru. Funkcija obravnave bo nato uporabila usmerjevalnik Next.js za navigacijo uporabnika do podanega URL-ja, v tem primeru zaščiten pot.
Določite končno točko Login API
Znotraj src/app ustvarite novo mapo in jo poimenujte api. Znotraj te mape dodajte novo prijava/route.js datoteko in vključite spodnjo kodo.
import { SignJWT } from"jose";
import { NextResponse } from"next/server";
import { getJwtSecretKey } from"@/libs/auth";
exportasyncfunctionPOST(request) {
const body = await request.json();
if (body.username "admin" && body.password "admin") {
const token = awaitnew SignJWT({
username: body.username,
})
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("30s")
.sign(getJwtSecretKey());
const response = NextResponse.json(
{ success: true },
{ status: 200, headers: { "content-type": "application/json" } }
);
response.cookies.set({
name: "token",
value: token,
path: "/",
});
return response;
}
return NextResponse.json({ success: false });
}
Primarna naloga tega API-ja je preverjanje poverilnic za prijavo, posredovanih v zahtevah POST, z uporabo lažnih podatkov.
Po uspešnem preverjanju ustvari šifriran žeton JWT, povezan s podatki o overjenem uporabniku. Na koncu odjemalcu pošlje uspešen odgovor, vključno z žetonom v odgovornih piškotkih; sicer vrne odgovor o statusu napake.
Izvedite logiko preverjanja žetonov
Začetni korak pri preverjanju pristnosti žetona je generiranje žetona po uspešni prijavi. Naslednji korak je implementacija logike za preverjanje žetona.
V bistvu boste uporabili jwtVerify funkcijo, ki jo zagotavlja Jose modul za preverjanje žetonov JWT, posredovanih z naslednjimi zahtevami HTTP.
V src imenik, ustvarite novega libs/auth.js datoteko in vključite spodnjo kodo.
import { jwtVerify } from"jose";
exportfunctiongetJwtSecretKey() {
const secret = process.env.NEXT_PUBLIC_JWT_SECRET_KEY;
if (!secret) {
thrownewError("JWT Secret key is not matched");
}
returnnew TextEncoder().encode(secret);
}
exportasyncfunctionverifyJwtToken(token) {
try {
const { payload } = await jwtVerify(token, getJwtSecretKey());
return payload;
} catch (error) {
returnnull;
}
}
Skrivni ključ se uporablja pri podpisovanju in preverjanju žetonov. S primerjavo dekodiranega podpisa žetona s pričakovanim podpisom lahko strežnik učinkovito preveri, ali je predloženi žeton veljaven, in na koncu odobri zahteve uporabnikov.
Ustvari .env datoteko v korenskem imeniku in dodajte edinstven skrivni ključ, kot sledi:
NEXT_PUBLIC_JWT_SECRET_KEY=your_secret_key
Ustvarite zaščiteno pot
Sedaj morate ustvariti pot, do katere lahko dobijo dostop samo overjeni uporabniki. Če želite to narediti, ustvarite novo protected/page.js datoteka v src/app imenik. V to datoteko dodajte naslednjo kodo.
exportdefaultfunctionProtectedPage() {
return<h1>Very protected pageh1>;
}
Ustvarite kljuko za upravljanje stanja avtentikacije
Ustvarite novo mapo v src imenik in ga poimenujte kavlji. Znotraj te mape dodajte novo useAuth/index.js datoteko in vključite spodnjo kodo.
"use client" ;
import React from"react";
import Cookies from"universal-cookie";
import { verifyJwtToken } from"@/libs/auth";exportfunctionuseAuth() {
const [auth, setAuth] = React.useState(null);
const getVerifiedtoken = async () => {
const cookies = new Cookies();
const token = cookies.get("token")?? null;
const verifiedToken = await verifyJwtToken(token);
setAuth(verifiedToken);
};
React.useEffect(() => {
getVerifiedtoken();
}, []);
return auth;
}
Ta kavelj upravlja stanje preverjanja pristnosti na strani odjemalca. Pridobi in preveri veljavnost žetona JWT v piškotkih z uporabo verifyJwtToken in nato nastavi podatke o overjenem uporabniku na avt država.
S tem omogoča drugim komponentam dostop do podatkov preverjenega uporabnika in njihovo uporabo. To je bistvenega pomena za scenarije, kot so posodobitve uporabniškega vmesnika na podlagi statusa preverjanja pristnosti, izdelava poznejših zahtev API ali upodabljanje različne vsebine na podlagi uporabniških vlog.
V tem primeru boste uporabili kavelj za upodabljanje drugačne vsebine na domov pot na podlagi stanja avtentikacije uporabnika.
Alternativni pristop, o katerem bi lahko razmislili, je rokovanje upravljanje stanja z orodjem Redux Toolkit ali zaposlitev a orodje za upravljanje države, kot je Jotai. Ta pristop zagotavlja, da lahko komponente dobijo globalni dostop do stanja preverjanja pristnosti ali katerega koli drugega definiranega stanja.
Kar naprej in odprite app/page.js datoteko, izbrišite predlogo kode Next.js in dodajte naslednjo kodo.
"use client" ;
import { useAuth } from"@/hooks/useAuth";
import Link from"next/link";
exportdefaultfunctionHome() {
const auth = useAuth();
return<>Public Home Page</h1>
Zgornja koda uporablja useAuth kavelj za upravljanje stanja avtentikacije. Pri tem pogojno upodobi javno domačo stran s povezavo do Vpiši se pot strani, ko uporabnik ni overjen, in prikaže odstavek za overjenega uporabnika.
Dodajte vmesno programsko opremo za uveljavitev pooblaščenega dostopa do zaščitenih poti
V src imenik, ustvarite novega vmesna programska oprema.js datoteko in dodajte spodnjo kodo.
import { NextResponse } from"next/server";
import { verifyJwtToken } from"@/libs/auth";const AUTH_PAGES = ["/login"];
const isAuthPages = (url) => AUTH_PAGES.some((page) => page.startsWith(url));
exportasyncfunctionmiddleware(request) {
const { url, nextUrl, cookies } = request;
const { value: token } = cookies.get("token")?? { value: null };
const hasVerifiedToken = token && (await verifyJwtToken(token));
const isAuthPageRequested = isAuthPages(nextUrl.pathname);if (isAuthPageRequested) {
if (!hasVerifiedToken) {
const response = NextResponse.next();
response.cookies.delete("token");
return response;
}
const response = NextResponse.redirect(new URL(`/`, url));
return response;
}if (!hasVerifiedToken) {
const searchParams = new URLSearchParams(nextUrl.searchParams);
searchParams.set("next", nextUrl.pathname);
const response = NextResponse.redirect(
new URL(`/login?${searchParams}`, url)
);
response.cookies.delete("token");
return response;
}return NextResponse.next();
}
exportconst config = { matcher: ["/login", "/protected/:path*"] };
Ta koda vmesne programske opreme deluje kot stražar. Preverja, ali so uporabniki, ko želijo dostopati do zaščitenih strani, overjeni in pooblaščeni za dostop do poti, poleg tega pa nepooblaščene uporabnike preusmeri na stran za prijavo.
Zaščita aplikacij Next.js
Preverjanje pristnosti žetonov je učinkovit varnostni mehanizem. Vendar to ni edina razpoložljiva strategija za zaščito vaših aplikacij pred nepooblaščenim dostopom.
Za krepitev aplikacij pred dinamično kibernetsko varnostjo je pomembno sprejeti celovito varnost pristop, ki celovito obravnava morebitne varnostne vrzeli in ranljivosti, da zagotovi temeljito zaščito.