Saate kohandatud JWT-põhise autentimisrakenduse abil oma Next.js rakenduse autentimisloogika üle paremini juhtida.
Token autentimine on populaarne strateegia, mida kasutatakse veebi- ja mobiilirakenduste kaitsmiseks volitamata juurdepääsu eest. Programmis Next.js saate kasutada Next-auth'i pakutavaid autentimisfunktsioone.
Teise võimalusena saate JSON Web Tokens (JWT) abil välja töötada kohandatud märgipõhise autentimissüsteemi. Seda tehes tagate, et teil on suurem kontroll autentimisloogika üle; sisuliselt kohandades süsteemi täpselt teie projekti nõuetele vastavaks.
Seadistage Next.js projekt
Alustamiseks installige Next.js, käivitades oma terminalis alloleva käsu.
npx create-next-app@latest next-auth-jwt --experimental-app
See juhend kasutab Next.js 13, mis sisaldab rakenduste kataloogi.
Järgmisena installige need sõltuvused oma projekti kasutades npm, sõlme paketihaldur.
npm install jose universal-cookie
Jose on JavaScripti moodul, mis pakub utiliitide komplekti JSON Web Tokenidega töötamiseks
universaalne küpsis sõltuvus pakub lihtsat viisi brauseri küpsistega töötamiseks nii kliendi- kui ka serveripoolses keskkonnas.Selle projekti koodi leiate siit GitHubi hoidla.
Looge sisselogimisvormi kasutajaliides
Ava src/app kataloogi, looge uus kaust ja andke sellele nimi Logi sisse. Lisage sellesse kausta uus page.js faili ja lisage allolev kood.
"use client";
import { useRouter } from"next/navigation";
exportdefaultfunctionLoginPage() {
return (
Ülaltoodud kood loob sisselogimislehe funktsionaalse komponendi, mis muudab brauseris lihtsa sisselogimisvormi, mis võimaldab kasutajatel sisestada kasutajanime ja parooli.
The kasuta klienti avaldus koodis tagab, et ainult serveri ja ainult kliendi koodi vahel deklareeritakse piir rakendus kataloog.
Sel juhul kasutatakse seda deklareerimiseks, et sisselogimislehel olev kood, eriti käepide Esitafunktsiooni teostatakse ainult kliendil; vastasel juhul kuvab Next.js veateate.
Nüüd määratleme koodi käepide Esita funktsiooni. Lisage funktsionaalse komponendi sisse järgmine kood.
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");
}
};
Sisselogimise autentimise loogika haldamiseks kogub see funktsioon sisselogimisvormilt kasutaja mandaadid. Seejärel saadab see API lõpp-punktile POST-päringu, edastades kontrollimiseks kasutaja üksikasjad.
Kui mandaadid on kehtivad, näitab, et sisselogimisprotsess oli edukas – API tagastab vastuses eduka oleku. Töötleja funktsioon kasutab seejärel Next.js ruuterit, et navigeerida kasutaja määratud URL-ile, antud juhul kaitstud tee.
Määrake sisselogimise API lõpp-punkt
Sees src/app kataloogi, looge uus kaust ja andke sellele nimi api. Lisage sellesse kausta uus login/route.js faili ja lisage allolev kood.
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 });
}
Selle API peamine ülesanne on kontrollida POST-i päringutes edastatud sisselogimismandaate, kasutades näidisandmeid.
Pärast edukat kinnitamist genereerib see krüptitud JWT-märgi, mis on seotud autentitud kasutaja üksikasjadega. Lõpuks saadab see kliendile eduka vastuse, sealhulgas vastuseküpsistes oleva märgi; vastasel juhul tagastab see tõrkeoleku vastuse.
Rakendage Token Verification Logic
Tokeni autentimise esimene samm on loa genereerimine pärast edukat sisselogimisprotsessi. Järgmine samm on loa kontrollimise loogika rakendamine.
Põhimõtteliselt kasutate jwtKinnitage pakutav funktsioon Jose moodul, et kontrollida järgnevate HTTP-päringutega edastatud JWT-märke.
Aastal src kataloog, looge uus libs/auth.js faili ja lisage allolev kood.
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;
}
}
Salavõtit kasutatakse märkide allkirjastamisel ja kontrollimisel. Võrreldes dekodeeritud märgi allkirja eeldatava allkirjaga, saab server tõhusalt kontrollida, kas antud luba on kehtiv, ja lõpuks volitada kasutajate päringuid.
Loo .env faili juurkataloogi ja lisage kordumatu salajane võti järgmiselt:
NEXT_PUBLIC_JWT_SECRET_KEY=your_secret_key
Looge kaitstud marsruut
Nüüd peate looma marsruudi, millele pääsevad juurde ainult autentitud kasutajad. Selleks looge uus Protected/page.js faili src/app kataloog. Lisage sellesse faili järgmine kood.
exportdefaultfunctionProtectedPage() {
return<h1>Very protected pageh1>;
}
Looge autentimisoleku haldamiseks konks
Looge kaustas uus kaust src kataloog ja nimetage see konksud. Lisage sellesse kausta uus useAuth/index.js faili ja lisage allolev kood.
"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;
}
See konks haldab autentimisolekut kliendi poolel. See hangib ja kontrollib küpsistes oleva JWT-märgi kehtivust, kasutades VerifyJwtToken funktsiooni ja määrab seejärel autentitud kasutaja üksikasjad väärtusele aut olek.
Seda tehes võimaldab see teistel komponentidel juurdepääsu autentitud kasutaja teabele ja seda kasutada. See on oluline selliste stsenaariumide puhul nagu kasutajaliidese värskenduste tegemine autentimise oleku alusel, järgnevate API päringute tegemine või kasutajarollide põhjal erineva sisu renderdamine.
Sel juhul kasutate konksu erineva sisu renderdamiseks Kodu marsruut, mis põhineb kasutaja autentimisolekul.
Alternatiivne lähenemisviis, mida võiksite kaaluda, on käsitlemine oleku haldamine Reduxi tööriistakomplekti abil või kasutades a riigihaldustööriist nagu Jotai. See lähenemisviis tagab, et komponendid saavad globaalse juurdepääsu autentimisolekule või mis tahes muule määratletud olekule.
Mine edasi ja avage app/page.js kustutage kood Next.js ja lisage järgmine kood.
"use client" ;
import { useAuth } from"@/hooks/useAuth";
import Link from"next/link";
exportdefaultfunctionHome() {
const auth = useAuth();
return<>Public Home Page</h1>
Ülaltoodud kood kasutab useAuth konks autentimisoleku haldamiseks. Seejuures muudab see tingimuslikult avaliku kodulehe lingiga Logi sisse lehe marsruut, kui kasutaja ei ole autentitud, ja kuvab lõigu autentitud kasutaja jaoks.
Lisage vahevara, et jõustada volitatud juurdepääs kaitstud marsruutidele
Aastal src kataloog, looge uus vahevara.js faili ja lisage allolev kood.
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*"] };
See vahevara kood toimib valvurina. See kontrollib, et kui kasutajad soovivad juurdepääsu kaitstud lehtedele, on nad autentitud ja volitatud marsruutidele juurde pääsema, lisaks juhib volitamata kasutajad sisselogimislehele.
Next.js rakenduste turvamine
Token autentimine on tõhus turvamehhanism. See pole aga ainus saadaolev strateegia teie rakenduste kaitsmiseks volitamata juurdepääsu eest.
Rakenduste tugevdamiseks dünaamilise küberjulgeoleku maastiku vastu on oluline võtta kasutusele kõikehõlmav turvalisus lähenemisviisi, mis käsitleb terviklikult võimalikke turvalünki ja turvaauke, et tagada põhjalik kaitse.