Özel JWT tabanlı kimlik doğrulama uygulaması aracılığıyla Next.js uygulamanızın kimlik doğrulama mantığı üzerinde daha fazla kontrole sahip olun.

Token kimlik doğrulaması, web ve mobil uygulamaları yetkisiz erişime karşı korumak için kullanılan popüler bir stratejidir. Next.js'de Next-auth tarafından sağlanan kimlik doğrulama özelliklerinden yararlanabilirsiniz.

Alternatif olarak, JSON Web Belirteçlerini (JWT'ler) kullanarak özel belirteç tabanlı bir kimlik doğrulama sistemi geliştirmeyi tercih edebilirsiniz. Bunu yaparak, kimlik doğrulama mantığı üzerinde daha fazla kontrole sahip olduğunuzdan emin olursunuz; esas olarak, sistemi projenizin gereksinimlerine tam olarak uyacak şekilde özelleştirmek.

Next.js Projesi Oluşturma

Başlamak için aşağıdaki komutu terminalinizde çalıştırarak Next.js'yi yükleyin.

npx create-next-app@latest next-auth-jwt --experimental-app

Bu kılavuzdan yararlanılacak Uygulama dizinini içeren Next.js 13.

Daha sonra, bu bağımlılıkları kullanarak projenize yükleyin. npm, Düğüm Paketi Yöneticisi.

instagram viewer
npm install jose universal-cookie

Jose JSON Web Belirteçleri ile çalışmak için bir dizi yardımcı program sağlayan bir JavaScript modülüdür. evrensel çerez bağımlılık, hem istemci tarafı hem de sunucu tarafı ortamlarında tarayıcı çerezleriyle çalışmanın basit bir yolunu sağlar.

Bu projenin kodunu burada bulabilirsiniz GitHub deposu.

Oturum Açma Formu Kullanıcı Arayüzünü Oluşturun

kaynak/uygulama dizini açın, yeni bir klasör oluşturun ve ona bir ad verin giriş yapmak. Bu klasörün içine yeni bir tane ekleyin page.js Dosyayı açın ve aşağıdaki kodu ekleyin.

"use client";
import { useRouter } from"next/navigation";

exportdefaultfunctionLoginPage() {
return (


Yukarıdaki kod, kullanıcıların bir kullanıcı adı ve parola girmesine izin vermek için tarayıcıda basit bir oturum açma formu oluşturacak bir oturum açma sayfası işlevsel bileşeni oluşturur.

istemciyi kullan Koddaki ifade, yalnızca sunucu ve yalnızca istemci kodu arasında bir sınırın bildirilmesini sağlar. uygulama dizin.

Bu durumda, giriş sayfasındaki kodun, özellikle de tanıtıcıGönderişlev yalnızca istemcide yürütülür; aksi halde Next.js bir hata verecektir.

Şimdi bu işlemin kodunu tanımlayalım. tanıtıcıGönder işlev. İşlevsel bileşenin içine aşağıdaki kodu ekleyin.

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");
}
 };

Oturum açma kimlik doğrulama mantığını yönetmek için bu işlev, oturum açma formundaki kullanıcı kimlik bilgilerini yakalar. Daha sonra doğrulama için kullanıcı ayrıntılarını ileten bir API uç noktasına bir POST isteği gönderir.

Kimlik bilgileri geçerliyse, oturum açma işleminin başarılı olduğunu gösterir; API, yanıtta bir başarı durumu döndürür. İşleyici işlevi daha sonra kullanıcıyı belirli bir URL'ye yönlendirmek için Next.js'nin yönlendiricisini kullanacaktır; bu durumda, korumalı rota.

Oturum Açma API Uç Noktasını Tanımlayın

İçinde kaynak/uygulama dizini açın, yeni bir klasör oluşturun ve adlandırın API. Bu klasörün içine yeni bir tane ekleyin giriş/rota.js Dosyayı açın ve aşağıdaki kodu ekleyin.

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 });
}

Bu API'nin birincil görevi, sahte verileri kullanarak POST isteklerinde iletilen oturum açma kimlik bilgilerini doğrulamaktır.

Başarılı doğrulamanın ardından, kimliği doğrulanmış kullanıcı ayrıntılarıyla ilişkili şifrelenmiş bir JWT belirteci oluşturur. Son olarak, yanıt çerezlerindeki belirteç de dahil olmak üzere müşteriye başarılı bir yanıt gönderir; aksi takdirde bir arıza durumu yanıtı döndürür.

Belirteç Doğrulama Mantığını Uygulama

Belirteç kimlik doğrulamasındaki ilk adım, başarılı bir oturum açma işleminden sonra belirteci oluşturmaktır. Bir sonraki adım, jeton doğrulama mantığını uygulamaktır.

Temel olarak, şunları kullanacaksınız: jwtDoğrula tarafından sağlanan işlev Jose Sonraki HTTP istekleriyle iletilen JWT belirteçlerini doğrulamak için modül.

İçinde kaynak dizin, yeni bir tane oluştur libs/auth.js Dosyayı açın ve aşağıdaki kodu ekleyin.

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;
}
}

Gizli anahtar, tokenlerin imzalanması ve doğrulanması için kullanılır. Sunucu, kodu çözülmüş belirteç imzasını beklenen imzayla karşılaştırarak, sağlanan belirtecin geçerli olduğunu etkili bir şekilde doğrulayabilir ve sonuçta kullanıcıların isteklerini yetkilendirebilir.

Yaratmak .env kök dizindeki dosyaya gidin ve aşağıdaki gibi benzersiz bir gizli anahtar ekleyin:

NEXT_PUBLIC_JWT_SECRET_KEY=your_secret_key

Korumalı Rota Oluşturma

Artık yalnızca kimliği doğrulanmış kullanıcıların erişebileceği bir rota oluşturmanız gerekiyor. Bunu yapmak için yeni bir korumalı/page.js dosyadaki kaynak/uygulama dizin. Bu dosyanın içine aşağıdaki kodu ekleyin.

exportdefaultfunctionProtectedPage() {
return<h1>Very protected pageh1>;
}

Kimlik Doğrulama Durumunu Yönetmek için Kanca Oluşturun

İçinde yeni bir klasör oluşturun kaynak dizini ve adını verin kancalar. Bu klasörün içine yeni bir tane ekleyin useAuth/index.js Dosyayı açın ve aşağıdaki kodu ekleyin.

"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;
}

Bu kanca, istemci tarafındaki kimlik doğrulama durumunu yönetir. Çerezlerde bulunan JWT belirtecinin geçerliliğini aşağıdakileri kullanarak alır ve doğrular: doğrulamaJwtToken işlevi kullanır ve ardından kimliği doğrulanmış kullanıcı ayrıntılarını yetki durum.

Bunu yaparak, diğer bileşenlerin kimliği doğrulanmış kullanıcının bilgilerine erişmesine ve bunları kullanmasına olanak tanır. Bu, kimlik doğrulama durumuna göre kullanıcı arayüzü güncellemeleri yapmak, sonraki API isteklerini yapmak veya kullanıcı rollerine göre farklı içerik oluşturmak gibi senaryolar için gereklidir.

Bu durumda, kancayı farklı içerik oluşturmak için kullanacaksınız. Ev Bir kullanıcının kimlik doğrulama durumuna göre rota.

Göz önünde bulundurabileceğiniz alternatif bir yaklaşım, Redux Araç Kitini kullanarak durum yönetimi veya istihdam etmek Jotai gibi durum yönetimi aracı. Bu yaklaşım, bileşenlerin kimlik doğrulama durumuna veya tanımlanmış herhangi bir başka duruma küresel erişim elde edebilmesini garanti eder.

Devam edin ve açın app/page.js dosyasını açın, ortak metin Next.js kodunu silin ve aşağıdaki kodu ekleyin.

"use client" ;

import { useAuth } from"@/hooks/useAuth";
import Link from"next/link";
exportdefaultfunctionHome() {
const auth = useAuth();
return<>

Public Home Page</h1>

Yukarıdaki kod şunu kullanır: yetkilendirmeyi kullan kimlik doğrulama durumunu yönetmek için kanca. Bunu yaparken, şartlı olarak, bir bağlantı içeren genel bir ana sayfa oluşturur. giriş yapmak Kullanıcının kimliği doğrulanmadığında sayfa rotasını belirler ve kimliği doğrulanan kullanıcı için bir paragraf görüntüler.

Korunan Yollara Yetkili Erişimi Zorunlu Hale Getirmek için Bir Ara Yazılım Ekleme

İçinde kaynak dizin, yeni bir tane oluştur ara yazılım.js Dosyayı açın ve aşağıdaki kodu ekleyin.

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*"] };

Bu ara yazılım kodu bir koruma görevi görür. Kullanıcılar korumalı sayfalara erişmek istediklerinde, kimliklerinin doğrulandığından ve rotalara erişim yetkisine sahip olduğundan emin olmak için kontrol yapar ve ayrıca yetkisiz kullanıcıları giriş sayfasına yönlendirir.

Next.js Uygulamalarının Güvenliğini Sağlama

Token kimlik doğrulaması etkili bir güvenlik mekanizmasıdır. Ancak uygulamalarınızı yetkisiz erişime karşı korumak için kullanabileceğiniz tek strateji bu değildir.

Uygulamaları dinamik siber güvenlik ortamına karşı güçlendirmek için kapsamlı bir güvenlik yaklaşımı benimsemek önemlidir. kapsamlı garanti sağlamak için potansiyel güvenlik açıklarını ve güvenlik açıklarını bütünsel olarak ele alan bir yaklaşım koruma.