Günümüzde web uygulamalarında güvenlik, en öncelikli konulardan biridir. Verileri güvenli bir şekilde yönetmek ve kullanıcıların kimliklerini doğrulamak için JSON Web Tokens (JWT) en popüler yöntemlerden biri haline gelmiştir. Bu makalede, Node.js ve Express kullanarak JWT uygulamasının nasıl kurulacağını adım adım keşfedeceğiz.
JWT, bir json objesini güvenli bir şekilde taşıyan bir web standartıdır. Token, kullanıcı bilgilerini, yetkilendirme verilerini ve diğer bilgileri içerir. Temel olarak, üç ana parçadan oluşmaktadır:
JWT uygulaması kurmak için öncelikle Node.js ve Express ortamımızı hazırlamalıyız. Aşağıda adım adım uygulama rehberimizi bulabilirsiniz.
İlk olarak, Node.js ve npm'yi yüklemeniz gerekiyor. Node.js’in en güncel sürümünü resmi web sitesinden indirebilirsiniz.
Projeniz için bir klasör oluşturun ve bu klasörde npm init komutunu çalıştırarak bir Node.js projesi başlatın. Bundan sonra aşağıdaki komutu kullanarak Express ve JWT kütüphanelerini yükleyeceğiz:
npm install express jsonwebtoken body-parser
Şimdi, projemizde kullanacağımız temel dosyaları oluşturalım. Aşağıdaki dosya yapısını oluşturun:
app.js dosyasını açın ve temel Express sunucusunu kurun:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.listen(3000, () => {
console.log('Sunucu 3000 portunda çalışıyor');
});
JWT ile kullanıcı doğrulaması için routes.js dosyasını oluşturun ve kullanıcıların token alabileceği bir endpoint tanımlayın.
const jwt = require('jsonwebtoken');
app.post('/login', (req, res) => {
const user = { id: 1 }; // Bu kullanıcı bilgileri bir veritabanından alınmalı
const token = jwt.sign({user}, 'secretkey'); // 'secretkey' güvenli bir anahtar olmalı
res.json({ token });
});
JWT doğrulaması ile korunan rotalar oluşturmak için bir middleware fonksiyonu kullanacağız:
function verifyToken(req, res, next) {
const token = req.headers['authorization'];
if (!token) return res.sendStatus(403);
jwt.verify(token, 'secretkey', (err, decoded) => {
if (err) return res.sendStatus(403);
req.user = decoded;
next();
});
}
app.get('/protected', verifyToken, (req, res) => {
res.json({ message: 'Bu korunan bir alan' });
});
JSON Web Tokens (JWT), web uygulamalarında güvenli kimlik doğrulama ve veri taşımak için kullanılan modern bir standarttır. Kullanıcıların kimlik bilgilerini güvenli bir biçimde doğrulamak, yetkilendirme işlemlerini gerçekleştirmek ve veri paylaşımını sağlamak için etkili bir yol sunar. Ancak, pek çok kişi JWT'yi kullanmaya başlarken, onun neden bu kadar popüler olduğunu merak eder.
JWT, üç ana bileşenden oluşur: header, payload ve signature. Bu bileşenler, token’ın güvenliğini ve geçerliliğini garanti eder. Header kısmı, token’ın tipini ve kullanılan algoritmayı belirtirken, payload kısmı kullanıcının kimlik bilgilerini içerir. Signature ise, header ve payload’un kullanılarak oluşturulan kriptografik bir imzadır.
JWT'nin en önemli avantajlarından biri, sunucu ile istemci arasında bilgi taşımanın kolay ve güvenli bir yolunu sunmasıdır. Tokenlar, oturum açma aşamasında oluşturuldukları için, bir daha sunucuya yapılacak her istekte gönderilerek kullanıcı kimliğini doğrulamaktadır. Bu, sunucu yükünü hafifletmekte ve ölçeklenebilirliği artırmaktadır.
Node.js, JavaScript’i sunucu tarafında çalıştırmaya yarayan bir platformdur. Ölçeklenebilir uygulamalar geliştirmek için tasarlanmış bir yapıdır ve non-blocking I/O özelliği sayesinde yüksek performans sunar. Express ise bu platform üzerinde çalışan, minimal ve esnek bir web uygulama çatısıdır. Basit yapılandırması ve genişletilebilirliği ile geliştiricilere hızlı bir geliştirme süreci sağlar.
Node.js ve Express, birlikte güçlü bir çözümdür. Geliştiriciler, Node.js ile hızlı ve performanslı sunucular oluştururken, Express ile uygulamalarının yönlendirme ve middleware ihtiyaçlarını karşılayabilirler. Ayrıca, JWT gibi modern güvenlik çözümleriyle entegre olması açısından da ideal bir seçimdir.
Birçok web uygulaması, kullanıcıların güvenli bir şekilde kimlik doğrulaması yapması gerektiği için Node.js ve Express’in bu özellikleri, JWT ile birleştiğinde, güçlü ve güvenli bir uygulama geliştirme ortamı sunar.
JWT tabanlı bir uygulama geliştirmek için ihtiyacınız olan ilk adım, gerekli tüm araçları kurmaktır. Node.js ve npm (Node Package Manager) sisteminizi hazırlamak için gereken ortamdır. Node.js’in en son sürümünü installations sayfasından indirebilirsiniz. ان instalasyonu tamamladıktan sonra, npm ile gerekli kütüphaneleri yüklemek için aşağıdaki komutları terminalde çalıştırmanız yeterlidir:
npm install express jsonwebtoken body-parser
Bu komut, Express framework'u ve JWT kütüphanesini, ayrıca body-parser modülünü yükleyecektir. Body-parser, POST istekleriyle gelen verileri kolaylıkla almanızı sağlar.
Yukarıdaki adımların ardından, projeniz için bir klasör oluşturup ilgili dosya yapısını oluşturmanız gerekecek. Aşağıda bu aşamaları detaylandırarak, projenizin temellerini nasıl atabileceğinizi görebilirsiniz:
Gerekli her şey kurulduktan sonra, uygulamanızın işleyişini sağlamak için Express sunucusunu kurmak üzere sonraki adımlara geçebiliriz.
Node.js, JavaScript'i sunucu tarafında çalıştırmak için popüler bir platformdur. Web uygulamaları geliştirmek isteyen bir geliştirici olarak, yeni bir projeye başlamak için ilk adım, sistemi doğru bir şekilde kurmaktır. İşte yeni bir Node.js projesi oluşturmanın adımları:
Adım 1: Proje Klasörü Oluşturma
mkdir jwt-example komutunu kullanarak bir klasör oluşturabilirsiniz.Adım 2: Node.js Projesini Başlatma
cd jwt-examplenpm init komutunu çalıştırın. Bu komut, projenize ait temel bilgileri toplamanızı sağlayacaktır. package.json dosyası oluşturulacaktır.Artık Node.js projenizi oluşturmanın temelleri tamamlandı. Bu noktadan sonra Express framework'ünü projeye dahil etme aşamasına geçebiliriz.
Express, Node.js üzerinde çalışan popüler ve esnek bir web uygulama çatısıdır. Geliştirici dostu yapısı sayesinde, hızlı bir şekilde uygulama geliştirme sürecini kolaylaştırır. Express'i projenize dahil etmek için aşağıdaki adımları izleyebilirsiniz:
Adım 1: Express Kütüphanesinin Yüklenmesi
npm install expressAdım 2: Express'i Projeye Dahil Etme
const express = require('express');
const app = express();
app.listen(3000, () => {
console.log('Sunucu 3000 portunda çalışıyor');
});
Express'i başarılı bir şekilde projeye dahil ederek, sağlam bir temel oluşturmuş olduk. Şimdi sıra, uygulama içerisinde JSON Web Token (JWT) kütüphanesini kurmaya geldi.
JWT, kullanıcı kimlik doğrulamasında ve veri taşınmasında etkin bir çözüm sunmaktadır. Express uygulamanızda JWT'yi kullanabilmek için gerekli adımları izlemelisiniz:
Adım 1: JWT Kütüphanesinin Yüklenmesi
npm install jsonwebtokennpm install body-parser
Adım 2: JWT Kütüphanesini Projeye Dahil Etme
const jwt = require('jsonwebtoken');
Her aşamayı uyguladıktan sonra, Node.js ile JWT tabanlı bir uygulama geliştirmenin ilk temel taşlarını oluşturmuş oldunuz. Sonraki adımlarda, kullanıcılar için JWT token üretimi ve güvenli rotalar oluşturma gibi işlemleri gerçekleştireceğiz.
JWT tabanlı bir uygulamanın belkemiğini oluşturan kullanıcı modeli, kimlik doğrulama süreçlerinin sağlıklı bir şekilde çalışması için kritik bir öneme sahiptir. Kullanıcı modelinin doğru bir şekilde tasarlanması, uygulamanızın güvenliğini ve veri bütünlüğünü artırır. Bu bölümde, temel bir kullanıcı modelinin nasıl oluşturulacağına dair ayrıntılı bir yol haritası sunacağız.
Öncelikle, kullanıcının hangi bilgilere sahip olacağını tanımlayan bir kullanıcı şeması oluşturmamız gerekiyor. Aşağıda, bir kullanıcı modelinin temel bileşenlerini içeren örnek bir JavaScript şeması verilmiştir:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: { type: String, required: true, unique: true },
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Bu model, kullanıcı adı, şifre ve e-posta gibi önemli bilgileri içermektedir. Ayrıca, mongoose kütüphanesi kullanılarak, MongoDB veritabanında kullanıcıların yönetilmesi için bir yapı oluşturulmuştur.
Kullanıcı doğrulama süreçlerinin sağlıklı bir şekilde işleyebilmesi için kayıt ve giriş işlemleri esastır. Bu noktada, kullanıcıların veritabanında kaydedilmesi ve giriş yaptıklarında doğrulanması için API endpoint'leri oluşturacağız.
Kullanıcı kayıt işlemi için bir endpoint oluşturarak, kullanıcının girdiği bilgileri doğrulayıp veritabanına kaydedebiliriz:
app.post('/register', async (req, res) => {
const { username, password, email } = req.body;
const hashedPassword = await bcrypt.hash(password, 10); // Şifreyi hash'leyerek güvenliğini artırıyoruz
const newUser = new User({ username, password: hashedPassword, email });
await newUser.save();
res.status(201).json({ message: 'Kullanıcı kaydedildi' });
});
Kullanıcı giriş kontrolünü yapmak için bir diğer endpoint'i oluşturalım:
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username });
if (!user) return res.status(400).json({ message: 'Kullanıcı bulunamadı' });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ message: 'Şifre yanlış' });
const token = jwt.sign({ id: user._id }, 'secretkey'); // Kullanıcı ID'sini token içine koyuyoruz
res.json({ token });
});
Kullanıcıların uygulamanızda kayıt olabilmesi ve giriş yapabilmesi için gerekli API endpoint'lerini oluşturmak son derece önemlidir. Bu süreçler, JWT ile birlikte kullanıcı doğrulamasının sağlığını korumak açısından kritik öneme sahiptir. Bu bölümde, hem kayıt hem de giriş işlemleri için API endpoint'lerini detaylandıracağız.
Kullanıcı kayıt işlemi için gerekli API, daha önce bahsetmiş olduğumuz /register endpoint’ini kapsamaktadır. Bu endpoint üzerinden, kullanıcı bilgileri toplanır ve güvenli bir şekilde veritabanında kaydedilir:
app.post('/register', async (req, res) => {
const { username, password, email } = req.body;
// Kullanıcı bilgilerini kontrol et; mevcutsa hata ver
const existingUser = await User.findOne({ email });
if (existingUser) return res.status(400).json({ message: 'Email zaten kullanılıyor' });
// Şifreyi hash'le
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = new User({ username, password: hashedPassword, email });
await newUser.save();
res.status(201).json({ message: 'Kullanıcı kaydedildi' });
});
Kullanıcı giriş işlemi için kullanıcı adı ve şifre kontrolü gerçekleştirilir. Eğer kullanıcı veritabanında mevcut ise, giriş başarılı sayılarak JWT token üretilir:
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username });
// Kullanıcı mevcut mu kontrol et
if (!user) return res.status(400).json({ message: 'Kullanıcı bulunamadı' });
// Şifreyi kontrol et
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ message: 'Şifre yanlış' });
// Token oluştur
const token = jwt.sign({ id: user._id }, 'secretkey');
res.json({ token });
});
Kullanıcıların kimliklerini doğrulamak için JWT kullanmak, modern web uygulamaları için bir zorunluluk haline gelmiştir. Bu aşamada, JWT'yi kullanan bir doğrulama sisteminin nasıl oluşturulacağını ve bu süreçte hangi adımların izleneceğini inceleyeceğiz.
JWT token'ının doğruluğunu kontrol etmek için middleware fonksiyonu oluşturmak oldukça faydalıdır. Bununla birlikte, korunan rotalara yalnızca geçerli token sahibi olan kullanıcılar erişim sağlayabilir:
function verifyToken(req, res, next) {
const token = req.headers['authorization'];
if (!token) return res.sendStatus(403); // Token yoksa 403 hatası döndür
jwt.verify(token, 'secretkey', (err, decoded) => {
if (err) return res.sendStatus(403); // Token geçersizse 403 döndür
req.user = decoded; // Kullanıcı bilgilerini istek nesnesine ekle
next(); // Bir sonraki middleware'e geç
});
}
Middleware fonksiyonu oluşturulduktan sonra, korunan rotaları belirleyebiliriz. Aşağıda, yalnızca geçerli token doğrulaması yapılmış kullanıcıların erişebileceği bir rota örneği bulabilirsiniz:
app.get('/protected', verifyToken, (req, res) => {
res.json({ message: 'Bu korunan bir alandır' });
});
Bu sayede, kullanıcıların yalnızca JWT token’ları ile güvendiğimiz durumlarda belirli verilere erişmesini sağlamış olduk. JWT ile kullanıcı doğrulama süreçlerinin sağlıklı bir şekilde işleyebilmesi için yukarıda belirtilen aşamaların dikkatlice uygulanması gerekmektedir.
Koruma sağlamak, modern web uygulamalarında belirleyici bir öneme sahiptir. Web uygulamaları, veri güvenliğini sağlamanın yanı sıra kullanıcıların yetkisiz erişimden korunmasını da gerektirir. Bu aşamada JWT (JSON Web Token) ve middleware kullanımı, koruma mekanizmasının önemli bir parçasıdır. Middleware, isteklerin ve yanıtların işlemden geçmeden önce uygulama tarafından işlenmesini sağlayarak, kullanıcı doğrulamasının düzenli bir şekilde gerçekleştirilmesine olanak tanır.
JWT middleware fonksiyonu, gelen her istekte authorization başlığında bir token olup olmadığını kontrol eder. Bir token bulunmuyorsa, kullanıcıya 403 Forbidden hatası döndürülür. Aşağıda, bu middleware fonksiyonunun nasıl oluşturulacağına dair bir örnek görebilirsiniz:
function verifyToken(req, res, next) {
const token = req.headers['authorization'];
if (!token) return res.sendStatus(403); // Token yoksa 403 hatası döndür
jwt.verify(token, 'secretkey', (err, decoded) => {
if (err) return res.sendStatus(403); // Token geçersizse 403 döndür
req.user = decoded; // Kullanıcı bilgilerini istek nesnesine ekle
next(); // Bir sonraki middleware'e geç
});
}
Bu fonksiyon, uygulamada güvenli bir katman sağlamak için kritik bir öneme sahiptir. Eğer kullanıcı geçerli bir token sağlamazsa, uygulama istekleri yönlendirilmeden hemen geri çevrilir. Ayrıca, geçerli bir token varsa, kullanıcı bilgileri req.user nesnesine eklenerek sonraki adımlar için kullanılabilir.
Bir sonraki adım, belirlediğimiz middleware'i kullanarak korunan rotalar oluşturmaktır. Örneğin, yalnızca geçerli token'a sahip kullanıcıların erişebileceği bir rota oluşturabiliriz:
app.get('/protected', verifyToken, (req, res) => {
res.json({ message: 'Bu korunan bir alandır' });
});
Bu yaklaşım, kullanıcıların JWT ile güvendiğimiz durumlarda belirli verilere erişmesini sağlar ve güvenliği artırır. Middleware ile sağlanan bu koruma mekanizması, kullanıcı doğrulama süreçlerinin sağlıklı bir şekilde işlemesine olanak tanır.
JWT ile uygulama geliştirirken, hata yönetimi ve güvenlik önlemleri almak son derece önemlidir. Geliştiricilerin, kullanıcıların karşılaşabileceği potansiyel hataları yönetmesi, uygulamanın güvenliğini artırmak ve kullanıcı deneyimini optimize etmek açısından kritik rol oynar.
Hata yönetimi, kullanıcıların yanlış girdiği durumlarda karşılaştıkları hataların sağlıklı bir şekilde ele alınmasını sağlar. Örneğin, geçersiz bir token ile birlikte sunucuya gelen isteklerde, belirtilen hatalar kullanıcıya net bir şekilde bildirilmelidir. JWT middleware fonksiyonunda, doğrulama hatalarını aşağıdaki şekilde yönetebilmekteyiz:
function verifyToken(req, res, next) {
const token = req.headers['authorization'];
if (!token) return res.status(403).json({ message: 'Token bulunamadı' });
jwt.verify(token, 'secretkey', (err, decoded) => {
if (err) return res.status(403).json({ message: 'Geçersiz token' });
req.user = decoded;
next();
});
}
Bu güncellenmiş fonksiyon, kullanıcıya hata kodları ile birlikte açıklayıcı mesajlar sunarak, geliştirici ve kullanıcı arasındaki iletişimi güçlendirir.
JWT kullanımı ile birlikte bazı güvenlik önlemleri almak da gereklidir. Öncelikle, secret key (gizli anahtar) maksimum güvenlik için daha karmaşık ve tahmin edilmesi zor olmalıdır. Ayrıca, token'in ömrünü kısıtlayarak, süre aşımına uğramış token'ların kullanılamasını sağlamalıyız. Aşağıda, bir token oluşturmada geçerlilik süresi ayarlama örneği görünebilir:
const token = jwt.sign({ id: user._id }, 'secretkey', { expiresIn: '1h' }); // Token 1 saat geçerli olacak
Belirtilen süre dolduğunda, kullanıcıların yeniden giriş yapmaları gerektiği konusunda bilgilendirilmesi, uygulamanın güvenliğinin artırılmasına yardımcı olur. Ayrıca, uygulamanın kullanıcı verilerini güvenli bir şekilde sakladığından emin olmak için HTTPS kullanmak ve kullanıcı şifrelerini hash'leyerek depolamak da önemli adımlardır.
Uygulamanız dost canlısı bir deneyim sunmak ve işlevselliğini sağlamak için sürekli test edilmelidir. Yeni bir projeye başladığınızda, her adımın doğru şekilde çalışıp çalışmadığını kontrol etmek ve herhangi bir hata veya eksiklik için düzenli olarak test yapmak gereklidir. İşte, test etme ve uygulamanızı çalıştırma adımlarını özetleyen önemli noktalar:
Test işlemleri için gerekli ortamı oluşturmak, uygulamanızın stabilitesini sağlamak için elzemdir. Geliştiriciler genellikle Postman gibi API test araçlarını kullanarak, API endpoint'lerini test edip olası hataları gözlemlemelidir. Örneğin, /register ve /login endpoint'lerini kullanarak kullanıcı kayıt ve giriş işlemlerinin doğru şekilde çalıştığını test edebilirsiniz.
Test süreçlerinde, farklı senaryolar oluşturmak kullanıcı doğrulama mekanizmanızın sağlıklı çalıştığından emin olmak için çok önemlidir. Yanlış kullanıcı bilgileri, geçersiz token senaryoları, ve başarılı giriş senaryolarını içeren geniş bir test yelpazesi oluşturmak, uygulamanızı stress test etmek için idealdir. Bu senaryoları sistematik bir şekilde takip ederek, uygulamanızdaki eksiklikleri tespit edebilir ve bunları giderebilirsiniz.
Son aşamada, uygulamanızın başarıyla çalıştığından emin olmak için sunucunuzu başlatmanız gerekecek. Daha önce eklediğiniz app.listen() fonksiyonuyla sunucuyu başlattıktan sonra API’nizin erişilebilir olup olmadığını kontrol edebilir, çeşitli cihazlardan veya Postman gibi farklı araçlardan test edebilirsiniz. Sunucu başarılı bir şekilde başlatıldığında, kullanıcı kimlik doğrulama ve yetkilendirme işlemleri düzgün şekilde çalışıyor olmalıdır.
Bu makalede, Node.js ve Express kullanarak JWT (JSON Web Token) ile güvenli bir kullanıcı doğrulama mekanizması oluşturmanın adımlarını detaylandırdık. JWT'nin yapı taşlarını, kullanım avantajlarını ve neden popüler hale geldiğini inceledik. Ayrıca, uygulamanızın temel yapısını ortaya koymak için gerekli adımları izledik ve güvenli bir kullanıcı modelinin nasıl oluşturulacağını, kayıt ve giriş işlemlerinin gerçekleştirilmesini ele aldık.
Kullanıcı doğrulama sürecinde JWT'nin nasıl kullanılacağını öğreterek, middleware fonksiyonları ile korunan rotaların oluşturulmasına, hata yönetimi ve güvenlik önlemlerinin nasıl alınacağına dair bilgiler verdik. Uygulamanızın test edilmesi ve çalıştırılmasıyla ilgili adımlar da bu makalede yer aldı.
Sonuç olarak, JWT ile kullanıcı doğrulama süreçlerinin doğru bir şekilde uygulanması, modern web uygulamalarının güvenliğini artırmak için kritik bir adımdır. Bu rehberdeki adımları takip ederek, güvenli ve ölçeklenebilir bir uygulama geliştirme yolunda önemli bir ilk adım atmış oldunuz.