{"id":34629,"date":"2025-11-20T00:20:47","date_gmt":"2025-11-19T21:20:47","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/"},"modified":"2025-11-20T00:20:47","modified_gmt":"2025-11-19T21:20:47","slug":"json-web-token-jwt-nedir-ve-neden-onemlidir","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/","title":{"rendered":"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?"},"content":{"rendered":"<p><title>Express.js&#8217;te JWT Kullan\u0131m\u0131: G\u00fcvenli Kimlik Do\u011frulama Rehberi<\/title><br \/>\n<body><\/p>\n<p>Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT&#8217;yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API&#8217;lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.<\/p>\n<h2>JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?<\/h2>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn mikroservis tabanl\u0131 ve API odakl\u0131 mimarilerinde, geleneksel oturum tabanl\u0131 kimlik do\u011frulama y\u00f6ntemleri genellikle yetersiz kalmaktad\u0131r. Her iste\u011fin durum bilgisini (state) sunucuda tutmak, \u00f6zellikle yatay \u00f6l\u00e7eklenebilirlik (horizontal scaling) s\u00f6z konusu oldu\u011funda ciddi performans ve y\u00f6netim zorluklar\u0131na yol a\u00e7ar. \u0130\u015fte tam bu noktada, JSON Web Token (JWT) devreye girerek, sunucuda herhangi bir oturum bilgisi tutulmas\u0131na gerek kalmadan, istemci ile sunucu aras\u0131nda g\u00fcvenli ve do\u011frulanabilir bilgi al\u0131\u015fveri\u015fini sa\u011flayan bir standart sunar.<\/p>\n<p>JWT, temel olarak \u00fc\u00e7 ana b\u00f6l\u00fcmden olu\u015fur: Ba\u015fl\u0131k (Header), Y\u00fck (Payload) ve \u0130mza (Signature). Bu \u00fc\u00e7 b\u00f6l\u00fcm, birer nokta (.) ile birle\u015ftirilerek tek bir dize (string) halinde temsil edilir. Ba\u015fl\u0131k k\u0131sm\u0131, token&#8217;\u0131n t\u00fcr\u00fcn\u00fc (genellikle &#8220;JWT&#8221;) ve kullan\u0131lan \u015fifreleme algoritmas\u0131n\u0131 (\u00f6rne\u011fin, HS256 veya RS256) i\u00e7erir. Y\u00fck k\u0131sm\u0131 ise, token&#8217;\u0131n kimin hakk\u0131nda oldu\u011funu, ne zaman olu\u015fturuldu\u011funu, ne zaman sona erece\u011fini ve kullan\u0131c\u0131ya \u00f6zel di\u011fer verileri (\u00f6rne\u011fin, kullan\u0131c\u0131 ID&#8217;si, rolleri) bar\u0131nd\u0131r\u0131r. Bu bilgilere &#8220;claim&#8221; ad\u0131 verilir ve standart (registered claims), genel (public claims) veya \u00f6zel (private claims) olabilirler. Son olarak, \u0130mza k\u0131sm\u0131, token&#8217;\u0131n b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc ve orijinalli\u011fini garanti eder. Ba\u015fl\u0131k ve Y\u00fck k\u0131s\u0131mlar\u0131 base64url ile kodland\u0131ktan sonra, sunucuda sadece sizin bildi\u011finiz gizli bir anahtar (secret key) kullan\u0131larak \u015fifrelenir. Bu, token&#8217;\u0131n i\u00e7eri\u011finin de\u011fi\u015ftirilmedi\u011finden emin olmam\u0131z\u0131 sa\u011flar. E\u011fer token&#8217;\u0131n herhangi bir k\u0131sm\u0131 de\u011fi\u015ftirilirse, imza ge\u00e7ersiz hale gelir ve sunucu token&#8217;\u0131 reddeder.<\/p>\n<p>JWT&#8217;nin en b\u00fcy\u00fck avantajlar\u0131ndan biri &#8220;stateless&#8221; (durum bilgisi tutmayan) yap\u0131s\u0131d\u0131r. Sunucu, her istekte gelen JWT&#8217;yi do\u011frulayarak kullan\u0131c\u0131n\u0131n kimli\u011fini ve yetkilerini an\u0131nda anlayabilir. Bu, sunucunun belle\u011finde oturum bilgisi tutma y\u00fck\u00fcn\u00fc ortadan kald\u0131r\u0131r, dolay\u0131s\u0131yla uygulaman\u0131z\u0131n daha kolay \u00f6l\u00e7eklenmesine olanak tan\u0131r. Bir kullan\u0131c\u0131 giri\u015f yapt\u0131\u011f\u0131nda, sunucu bir JWT olu\u015fturur ve istemciye geri g\u00f6nderir. \u0130stemci, bu token&#8217;\u0131 sonraki t\u00fcm yetkilendirme gerektiren isteklerde &#8220;Authorization&#8221; ba\u015fl\u0131\u011f\u0131nda (genellikle &#8220;Bearer&#8221; \u015femas\u0131yla) sunucuya geri g\u00f6nderir. Sunucu ise her istekte bu token&#8217;\u0131 do\u011frulayarak kullan\u0131c\u0131n\u0131n kimli\u011fini tespit eder ve ilgili i\u015flemi ger\u00e7ekle\u015ftirmesine izin verir. Bu y\u00f6ntem, \u00f6zellikle mobil uygulamalar, tek sayfal\u0131 uygulamalar (SPA&#8217;lar) ve mikroservis mimarileri i\u00e7in idealdir, \u00e7\u00fcnk\u00fc farkl\u0131 servisler ayn\u0131 gizli anahtar\u0131 kullanarak token&#8217;lar\u0131 do\u011frulayabilir ve b\u00f6ylece merkezi bir kimlik do\u011frulama servisine ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 azalt\u0131r. JWT, \u015fifrelenmi\u015f olmasa da (sadece kodlanm\u0131\u015ft\u0131r), imza sayesinde i\u00e7eri\u011finin de\u011fi\u015ftirilemez olmas\u0131yla \u00f6nemli bir g\u00fcvenlik katman\u0131 sunar.<\/p>\n<h2>Express.js Projesinde JWT Entegrasyonu Nas\u0131l Yap\u0131l\u0131r?<\/h2>\n<p>Express.js uygulaman\u0131za JWT entegrasyonu yapmak, birka\u00e7 temel ad\u0131mda ger\u00e7ekle\u015ftirilebilir. Bu s\u00fcre\u00e7, bir kullan\u0131c\u0131n\u0131n sisteme kaydolmas\u0131 veya giri\u015f yapmas\u0131yla ba\u015flar, ard\u0131ndan sunucunun bir JWT olu\u015fturup istemciye g\u00f6ndermesiyle devam eder. \u0130stemci, ald\u0131\u011f\u0131 bu token&#8217;\u0131 sonraki t\u00fcm yetkilendirilmi\u015f isteklere ekleyerek sunucuya geri g\u00f6nderir. \u015eimdi, bu ad\u0131mlar\u0131 detayl\u0131 bir \u015fekilde inceleyelim ve gerekli kod \u00f6rneklerini g\u00f6relim.<\/p>\n<p>\u00d6ncelikle, projemizi olu\u015ftural\u0131m ve gerekli paketleri kural\u0131m. Bir Node.js projesi ba\u015flatmak i\u00e7in terminalinizde \u015fu komutlar\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">\nnpm init -y\nnpm install express jsonwebtoken dotenv bcryptjs\n    <\/code><\/pre>\n<p><code>express<\/code> web \u00e7er\u00e7evesi, <code>jsonwebtoken<\/code> JWT olu\u015fturma ve do\u011frulama k\u00fct\u00fcphanesi, <code>dotenv<\/code> \u00e7evre de\u011fi\u015fkenlerini y\u00f6netmek i\u00e7in ve <code>bcryptjs<\/code> ise \u015fifreleri g\u00fcvenli bir \u015fekilde hashlemek i\u00e7in kullan\u0131lacakt\u0131r.<\/p>\n<h3>Kullan\u0131c\u0131 Kay\u0131t ve Giri\u015f Ak\u0131\u015f\u0131<\/h3>\n<p>Kullan\u0131c\u0131lar\u0131n sisteme g\u00fcvenli bir \u015fekilde kaydolmas\u0131 ve giri\u015f yapmas\u0131, JWT tabanl\u0131 kimlik do\u011frulaman\u0131n ilk ad\u0131m\u0131d\u0131r. Kay\u0131t i\u015flemi s\u0131ras\u0131nda kullan\u0131c\u0131 \u015fifreleri asla d\u00fcz metin olarak veritaban\u0131na kaydedilmemeli, bunun yerine g\u00fc\u00e7l\u00fc bir hash algoritmas\u0131 ile \u015fifrelenmelidir. Bcrypt bu i\u015flem i\u00e7in olduk\u00e7a pop\u00fcler ve g\u00fcvenli bir se\u00e7imdir. Giri\u015f i\u015flemi s\u0131ras\u0131nda ise, kullan\u0131c\u0131n\u0131n girdi\u011fi \u015fifre, veritaban\u0131ndaki hash ile kar\u015f\u0131la\u015ft\u0131r\u0131l\u0131r.<\/p>\n<p>A\u015fa\u011f\u0131daki \u00f6rnek kod blo\u011fu, basit bir kullan\u0131c\u0131 modeli, kay\u0131t ve giri\u015f rotalar\u0131n\u0131 g\u00f6stermektedir. Bu \u00f6rnekte veritaban\u0131 olarak basit bir dizi kullanaca\u011f\u0131z, ancak ger\u00e7ek bir uygulamada MongoDB, PostgreSQL gibi bir veritaban\u0131 kullanman\u0131z gerekecektir.<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ app.js\nconst express = require('express');\nconst jwt = require('jsonwebtoken');\nconst bcrypt = require('bcryptjs');\nrequire('dotenv').config(); \/\/ .env dosyas\u0131ndaki de\u011fi\u015fkenleri y\u00fckler\n\nconst app = express();\napp.use(express.json()); \/\/ Body'deki JSON verilerini parse etmek i\u00e7in\n\nconst users = []; \/\/ Ger\u00e7ek uygulamada buras\u0131 bir veritaban\u0131 olacakt\u0131r\n\n\/\/ JWT gizli anahtar\u0131 (g\u00fcvenli bir yerde saklanmal\u0131!)\nconst JWT_SECRET = process.env.JWT_SECRET || 'supersecretjwtkey';\n\n\/\/ Kullan\u0131c\u0131 Kay\u0131t Rotas\u0131\napp.post('\/register', async (req, res) => {\n    try {\n        const { username, password } = req.body;\n\n        \/\/ Kullan\u0131c\u0131 ad\u0131 kontrol\u00fc\n        if (users.some(user => user.username === username)) {\n            return res.status(400).send('Bu kullan\u0131c\u0131 ad\u0131 zaten mevcut.');\n        }\n\n        \/\/ \u015eifreyi hashleme\n        const hashedPassword = await bcrypt.hash(password, 10); \/\/ 10 salt rounds\n\n        const newUser = { id: users.length + 1, username, password: hashedPassword, roles: ['user'] };\n        users.push(newUser);\n\n        res.status(201).send('Kullan\u0131c\u0131 ba\u015far\u0131yla kaydedildi.');\n    } catch (error) {\n        console.error(error);\n        res.status(500).send('Sunucu hatas\u0131.');\n    }\n});\n\n\/\/ Kullan\u0131c\u0131 Giri\u015f Rotas\u0131\napp.post('\/login', async (req, res) => {\n    try {\n        const { username, password } = req.body;\n\n        \/\/ Kullan\u0131c\u0131y\u0131 bul\n        const user = users.find(u => u.username === username);\n        if (!user) {\n            return res.status(400).send('Kullan\u0131c\u0131 ad\u0131 veya \u015fifre yanl\u0131\u015f.');\n        }\n\n        \/\/ \u015eifreleri kar\u015f\u0131la\u015ft\u0131r\n        const isMatch = await bcrypt.compare(password, user.password);\n        if (!isMatch) {\n            return res.status(400).send('Kullan\u0131c\u0131 ad\u0131 veya \u015fifre yanl\u0131\u015f.');\n        }\n\n        \/\/ JWT olu\u015fturma\n        const token = jwt.sign(\n            { id: user.id, username: user.username, roles: user.roles },\n            JWT_SECRET,\n            { expiresIn: '1h' } \/\/ Token 1 saat sonra sona erecek\n        );\n\n        res.json({ token });\n    } catch (error) {\n        console.error(error);\n        res.status(500).send('Sunucu hatas\u0131.');\n    }\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n    console.log(<code class=\"language-\">Sunucu ${PORT} portunda \u00e7al\u0131\u015f\u0131yor.<\/code>);\n});\n    <\/code><\/pre>\n<p>Yukar\u0131daki kodda, <code>\/register<\/code> rotas\u0131 yeni bir kullan\u0131c\u0131 olu\u015ftururken \u015fifreyi hashler. <code>\/login<\/code> rotas\u0131 ise kullan\u0131c\u0131n\u0131n kimlik bilgilerini do\u011frulad\u0131ktan sonra <code>jwt.sign()<\/code> metodunu kullanarak bir JWT olu\u015fturur. Bu token, kullan\u0131c\u0131n\u0131n ID&#8217;si, kullan\u0131c\u0131 ad\u0131 ve rolleri gibi bilgileri i\u00e7erir ve 1 saat ge\u00e7erlilik s\u00fcresine sahiptir. Olu\u015fturulan token, istemciye JSON yan\u0131t\u0131 olarak geri g\u00f6nderilir.<\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: <code>.env<\/code> dosyan\u0131z\u0131 versiyon kontrol sistemlerine (Git gibi) asla y\u00fcklemeyin. <code>.gitignore<\/code> dosyan\u0131za <code>.env<\/code> ekleyerek gizli anahtarlar\u0131n\u0131z\u0131n g\u00fcvende kalmas\u0131n\u0131 sa\u011flay\u0131n.\n    <\/div>\n<h2>JWT ile Kimlik Do\u011frulama ve Yetkilendirme Mekanizmas\u0131<\/h2>\n<p>JWT&#8217;nin en g\u00fc\u00e7l\u00fc y\u00f6nlerinden biri, bir kez olu\u015fturulduktan sonra, sunucunun her iste\u011fi ayr\u0131 ayr\u0131 do\u011frulamak i\u00e7in kullanabilece\u011fi bir &#8220;pasaport&#8221; g\u00f6revi g\u00f6rmesidir. \u0130stemci, giri\u015f yapt\u0131ktan sonra ald\u0131\u011f\u0131 token&#8217;\u0131 sonraki t\u00fcm yetkilendirme gerektiren API isteklerinde sunucuya geri g\u00f6ndermelidir. Sunucu taraf\u0131nda ise bu token&#8217;\u0131n ge\u00e7erlili\u011fini kontrol eden ve kullan\u0131c\u0131 bilgilerini istek objesine ekleyen bir ara katman (middleware) fonksiyonu olu\u015fturulur. Bu middleware, Express.js uygulamalar\u0131nda kimlik do\u011frulama ve yetkilendirme s\u00fcre\u00e7lerinin merkezi bir par\u00e7as\u0131d\u0131r.<\/p>\n<h3>Do\u011frulama Middleware&#8217;i Yaz\u0131m\u0131<\/h3>\n<p>Bir JWT do\u011frulama middleware&#8217;i, gelen her iste\u011fin &#8220;Authorization&#8221; ba\u015fl\u0131\u011f\u0131n\u0131 kontrol eder. E\u011fer bu ba\u015fl\u0131kta ge\u00e7erli bir JWT varsa, token&#8217;\u0131 \u00e7\u00f6zer (verify) ve i\u00e7erdi\u011fi kullan\u0131c\u0131 bilgilerini (\u00f6rne\u011fin, kullan\u0131c\u0131 ID&#8217;si, rolleri) <code>req.user<\/code> gibi bir objeye ekleyerek bir sonraki i\u015fleyiciye aktar\u0131r. E\u011fer token yoksa veya ge\u00e7ersizse, iste\u011fi uygun bir hata koduyla reddeder. Bu yap\u0131, kod tekrar\u0131n\u0131 \u00f6nler ve uygulaman\u0131z\u0131n g\u00fcvenli\u011fini merkezi bir noktadan y\u00f6netmenizi sa\u011flar.<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ authMiddleware.js\nconst jwt = require('jsonwebtoken');\nrequire('dotenv').config();\n\nconst JWT_SECRET = process.env.JWT_SECRET || 'supersecretjwtkey';\n\nconst authenticateToken = (req, res, next) => {\n    const authHeader = req.headers['authorization'];\n    const token = authHeader && authHeader.split(' ')[1]; \/\/ \"Bearer TOKEN\" k\u0131sm\u0131ndan TOKEN'\u0131 al\n\n    if (token == null) {\n        return res.status(401).send('Eri\u015fim reddedildi: Token sa\u011flanmad\u0131.'); \/\/ Token yok\n    }\n\n    jwt.verify(token, JWT_SECRET, (err, user) => {\n        if (err) {\n            console.error('JWT do\u011frulama hatas\u0131:', err);\n            return res.status(403).send('Eri\u015fim reddedildi: Ge\u00e7ersiz token.'); \/\/ Token ge\u00e7ersiz\n        }\n        req.user = user; \/\/ Token'dan \u00e7\u00f6z\u00fclen kullan\u0131c\u0131 bilgilerini req objesine ekle\n        next(); \/\/ Bir sonraki middleware veya route handler'a ge\u00e7\n    });\n};\n\nmodule.exports = authenticateToken;\n    <\/code><\/pre>\n<p>Bu middleware, <code>authMiddleware.js<\/code> ad\u0131nda ayr\u0131 bir dosyada tan\u0131mlanabilir. Daha sonra, korumak istedi\u011finiz rotalara bu middleware&#8217;i ekleyebilirsiniz. \u00d6rne\u011fin, sadece giri\u015f yapm\u0131\u015f kullan\u0131c\u0131lar\u0131n eri\u015febilece\u011fi bir &#8220;profil&#8221; rotas\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ app.js (devam\u0131)\nconst authenticateToken = require('.\/authMiddleware');\n\n\/\/ Korumal\u0131 rota \u00f6rne\u011fi\napp.get('\/profile', authenticateToken, (req, res) => {\n    res.json({ message: <code class=\"language-\">Ho\u015f geldin, ${req.user.username}!<\/code>, user: req.user });\n});\n    <\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>\/profile<\/code> rotas\u0131na yap\u0131lan bir istek \u00f6nce <code>authenticateToken<\/code> middleware&#8217;inden ge\u00e7er. E\u011fer token ge\u00e7erliyse, <code>req.user<\/code> objesi doldurulur ve istek rotan\u0131n i\u015fleyicisine ula\u015f\u0131r. Aksi takdirde, middleware iste\u011fi 401 veya 403 hata koduyla sonland\u0131r\u0131r.<\/p>\n<h3>Kullan\u0131c\u0131 Rollerine G\u00f6re Yetkilendirme<\/h3>\n<p>Kimlik do\u011frulama, kullan\u0131c\u0131n\u0131n kim oldu\u011funu belirlerken; yetkilendirme, kullan\u0131c\u0131n\u0131n belirli bir kayna\u011fa veya i\u015fleme eri\u015fip eri\u015femeyece\u011fini belirler. JWT&#8217;nin &#8220;payload&#8221; k\u0131sm\u0131na kullan\u0131c\u0131 rolleri gibi yetkilendirme bilgilerini ekleyerek, \u00e7ok esnek bir yetkilendirme sistemi olu\u015fturabiliriz. \u00d6rne\u011fin, sadece &#8220;admin&#8221; rol\u00fcne sahip kullan\u0131c\u0131lar\u0131n eri\u015febilece\u011fi bir rota tan\u0131mlayal\u0131m:<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ authMiddleware.js (devam\u0131)\n\nconst authorizeRoles = (roles) => {\n    return (req, res, next) => {\n        if (!req.user || !req.user.roles) {\n            return res.status(403).send('Eri\u015fim reddedildi: Rol bilgisi eksik.');\n        }\n        const hasPermission = roles.some(role => req.user.roles.includes(role));\n        if (hasPermission) {\n            next();\n        } else {\n            res.status(403).send('Eri\u015fim reddedildi: Yetersiz yetki.');\n        }\n    };\n};\n\n\/\/ authMiddleware.js dosyas\u0131n\u0131n sonuna ekleyin\nmodule.exports = { authenticateToken, authorizeRoles };\n    <\/code><\/pre>\n<p>Ve bunu <code>app.js<\/code> dosyas\u0131nda kullanal\u0131m:<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ app.js (devam\u0131)\nconst { authenticateToken, authorizeRoles } = require('.\/authMiddleware');\n\n\/\/ Sadece adminlerin eri\u015febilece\u011fi bir rota\napp.get('\/admin-dashboard', authenticateToken, authorizeRoles(['admin']), (req, res) => {\n    res.json({ message: <code class=\"language-\">Admin paneline ho\u015f geldin, ${req.user.username}!<\/code> });\n});\n\n\/\/ Hem adminlerin hem de edit\u00f6rlerin eri\u015febilece\u011fi bir rota\napp.get('\/manage-content', authenticateToken, authorizeRoles(['admin', 'editor']), (req, res) => {\n    res.json({ message: <code class=\"language-\">\u0130\u00e7erik y\u00f6netimine ho\u015f geldin, ${req.user.username}!<\/code> });\n});\n    <\/code><\/pre>\n<p>Bu <code>authorizeRoles<\/code> middleware&#8217;i, bir dizi rol al\u0131r ve iste\u011fi yapan kullan\u0131c\u0131n\u0131n (<code>req.user<\/code> i\u00e7indeki) bu rollerden en az birine sahip olup olmad\u0131\u011f\u0131n\u0131 kontrol eder. E\u011fer kullan\u0131c\u0131 gerekli role sahipse, istek bir sonraki ad\u0131ma ge\u00e7er; aksi takdirde 403 (Forbidden) hatas\u0131 d\u00f6nd\u00fcr\u00fcl\u00fcr. Bu yap\u0131, uygulaman\u0131zdaki farkl\u0131 kullan\u0131c\u0131 tipleri i\u00e7in granular yetkilendirme sa\u011flaman\u0131za olanak tan\u0131r.<\/p>\n<h3>Ger\u00e7ek D\u00fcnya Senaryosu: Bir E-Ticaret API&#8217;sinde JWT Kullan\u0131m\u0131<\/h3>\n<p>Bir e-ticaret uygulamas\u0131nda JWT kullan\u0131m\u0131, hem kullan\u0131c\u0131 deneyimini iyile\u015ftirir hem de API g\u00fcvenli\u011fini art\u0131r\u0131r. Diyelim ki bir e-ticaret API&#8217;miz var ve bu API&#8217;de \u00fcr\u00fcnleri listeleme, sepete \u00fcr\u00fcn ekleme ve sipari\u015f verme gibi i\u015flevler bulunuyor. Bu senaryoda JWT&#8217;yi nas\u0131l entegre edece\u011fimizi inceleyelim.<\/p>\n<p>\u00d6ncelikle, t\u00fcm kullan\u0131c\u0131lar\u0131n \u00fcr\u00fcnleri listeleyebilmesi gerekti\u011fini, ancak sepete \u00fcr\u00fcn eklemek veya sipari\u015f vermek i\u00e7in giri\u015f yapm\u0131\u015f olmalar\u0131 gerekti\u011fini varsayal\u0131m. Ayr\u0131ca, sadece &#8220;admin&#8221; rol\u00fcne sahip kullan\u0131c\u0131lar\u0131n \u00fcr\u00fcn ekleyebilmesi veya mevcut \u00fcr\u00fcnleri d\u00fczenleyebilmesi gerekti\u011fini d\u00fc\u015f\u00fcnelim.<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ app.js (E-Ticaret Senaryosu)\nconst express = require('express');\nconst app = express();\nconst { authenticateToken, authorizeRoles } = require('.\/authMiddleware'); \/\/ Middleware'lerimizi dahil ettik\n\napp.use(express.json());\n\n\/\/ Basit bir \u00fcr\u00fcn listesi (ger\u00e7ekte veritaban\u0131ndan gelir)\nlet products = [\n    { id: 1, name: 'Laptop', price: 1200 },\n    { id: 2, name: 'Mouse', price: 25 },\n    { id: 3, name: 'Keyboard', price: 75 }\n];\n\n\/\/ 1. \u00dcr\u00fcnleri Listeleme (Herkese A\u00e7\u0131k Rota)\napp.get('\/api\/products', (req, res) => {\n    res.json(products);\n});\n\n\/\/ 2. Sepete \u00dcr\u00fcn Ekleme (Giri\u015f Yapm\u0131\u015f Kullan\u0131c\u0131lar)\napp.post('\/api\/cart\/add', authenticateToken, (req, res) => {\n    const { productId, quantity } = req.body;\n    const product = products.find(p => p.id === productId);\n\n    if (!product) {\n        return res.status(404).send('\u00dcr\u00fcn bulunamad\u0131.');\n    }\n\n    \/\/ Ger\u00e7ek uygulamada, kullan\u0131c\u0131n\u0131n sepetine ekleme i\u015flemi burada yap\u0131l\u0131r.\n    \/\/ req.user.id ile kullan\u0131c\u0131n\u0131n kimli\u011fini alabiliriz.\n    console.log(<code class=\"language-\">${req.user.username} (ID: ${req.user.id}) sepete ${product.name} \u00fcr\u00fcn\u00fcnden ${quantity} adet ekledi.<\/code>);\n    res.status(200).send(<code class=\"language-\">${product.name} sepete eklendi.<\/code>);\n});\n\n\/\/ 3. Sipari\u015f Verme (Giri\u015f Yapm\u0131\u015f Kullan\u0131c\u0131lar)\napp.post('\/api\/orders', authenticateToken, (req, res) => {\n    \/\/ req.body'den sipari\u015f detaylar\u0131n\u0131 al\n    const orderDetails = req.body;\n    \/\/ Ger\u00e7ek uygulamada, sipari\u015f veritaban\u0131na kaydedilir.\n    console.log(<code class=\"language-\">${req.user.username} (ID: ${req.user.id}) yeni bir sipari\u015f olu\u015fturdu:<\/code>, orderDetails);\n    res.status(201).send('Sipari\u015finiz ba\u015far\u0131yla al\u0131nd\u0131.');\n});\n\n\/\/ 4. Yeni \u00dcr\u00fcn Ekleme (Sadece Adminler)\napp.post('\/api\/products', authenticateToken, authorizeRoles(['admin']), (req, res) => {\n    const { name, price } = req.body;\n    const newProduct = { id: products.length + 1, name, price };\n    products.push(newProduct);\n    res.status(201).json(newProduct);\n});\n\n\/\/ 5. \u00dcr\u00fcn G\u00fcncelleme (Sadece Adminler)\napp.put('\/api\/products\/:id', authenticateToken, authorizeRoles(['admin']), (req, res) => {\n    const productId = parseInt(req.params.id);\n    const { name, price } = req.body;\n\n    const productIndex = products.findIndex(p => p.id === productId);\n    if (productIndex === -1) {\n        return res.status(404).send('\u00dcr\u00fcn bulunamad\u0131.');\n    }\n\n    products[productIndex] = { ...products[productIndex], name, price };\n    res.json(products[productIndex]);\n});\n\n\/\/ ... di\u011fer rotalar ve sunucu ba\u015flatma kodu ...\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n    console.log(<code class=\"language-\">E-Ticaret API'si ${PORT} portunda \u00e7al\u0131\u015f\u0131yor.<\/code>);\n});\n    <\/code><\/pre>\n<p>Bu senaryoda, <code>\/api\/products<\/code> rotas\u0131 herkese a\u00e7\u0131kt\u0131r ve herhangi bir kimlik do\u011frulamas\u0131 gerektirmez. Ancak, <code>\/api\/cart\/add<\/code> ve <code>\/api\/orders<\/code> gibi rotalar <code>authenticateToken<\/code> middleware&#8217;i ile korunmaktad\u0131r, yani bu i\u015flemleri yapmak i\u00e7in ge\u00e7erli bir JWT&#8217;ye sahip olmak zorunludur. Dahas\u0131, <code>\/api\/products<\/code> (POST) ve <code>\/api\/products\/:id<\/code> (PUT) gibi \u00fcr\u00fcn ekleme ve g\u00fcncelleme rotalar\u0131, hem <code>authenticateToken<\/code> hem de <code>authorizeRoles(['admin'])<\/code> middleware&#8217;lerini kullanarak sadece y\u00f6netici rol\u00fcne sahip kullan\u0131c\u0131lar\u0131n eri\u015fimine izin verir. Bu, e-ticaret platformunuzun farkl\u0131 kullan\u0131c\u0131 yetki seviyelerini g\u00fcvenli ve esnek bir \u015fekilde y\u00f6netmesini sa\u011flar. \u0130stemci taraf\u0131nda, kullan\u0131c\u0131 giri\u015f yapt\u0131ktan sonra ald\u0131\u011f\u0131 JWT&#8217;yi her istekte &#8220;Authorization: Bearer [token]&#8221; ba\u015fl\u0131\u011f\u0131yla g\u00f6ndermelidir.<\/p>\n<h2>JWT G\u00fcvenli\u011fini Art\u0131rma ve S\u0131k\u00e7a Yap\u0131lan Hatalardan Ka\u00e7\u0131nma<\/h2>\n<p>JWT&#8217;ler, sunduklar\u0131 \u00f6l\u00e7eklenebilirlik ve esneklikle modern uygulamalar i\u00e7in harika bir kimlik do\u011frulama \u00e7\u00f6z\u00fcm\u00fc olsa da, yanl\u0131\u015f kullan\u0131ld\u0131klar\u0131nda ciddi g\u00fcvenlik a\u00e7\u0131klar\u0131na yol a\u00e7abilirler. G\u00fcvenli\u011fi en \u00fcst d\u00fczeye \u00e7\u0131karmak ve yayg\u0131n hatalardan ka\u00e7\u0131nmak i\u00e7in dikkat etmeniz gereken baz\u0131 \u00f6nemli noktalar bulunmaktad\u0131r.<\/p>\n<h3>Refresh Token Mekanizmas\u0131<\/h3>\n<p>Eri\u015fim token&#8217;lar\u0131n\u0131n (access token) s\u00fcresi genellikle k\u0131sa tutulur (\u00f6rne\u011fin, 15 dakika ila 1 saat). Bu, token \u00e7al\u0131nsa bile sald\u0131rgan\u0131n s\u0131n\u0131rl\u0131 bir s\u00fcreye sahip olmas\u0131n\u0131 sa\u011flar. Ancak, her k\u0131sa s\u00fcrede kullan\u0131c\u0131dan tekrar giri\u015f yapmas\u0131n\u0131 istemek k\u00f6t\u00fc bir kullan\u0131c\u0131 deneyimi yarat\u0131r. Bu sorunu \u00e7\u00f6zmek i\u00e7in &#8220;Refresh Token&#8221; mekanizmas\u0131 kullan\u0131l\u0131r.<\/p>\n<p>Refresh token&#8217;lar, eri\u015fim token&#8217;lar\u0131ndan daha uzun \u00f6m\u00fcrl\u00fcd\u00fcr (\u00f6rne\u011fin, g\u00fcnler veya haftalar). Kullan\u0131c\u0131 giri\u015f yapt\u0131\u011f\u0131nda, hem k\u0131sa \u00f6m\u00fcrl\u00fc bir eri\u015fim token&#8217;\u0131 hem de uzun \u00f6m\u00fcrl\u00fc bir refresh token&#8217;\u0131 al\u0131r. Eri\u015fim token&#8217;\u0131 sona erdi\u011finde, istemci refresh token&#8217;\u0131 kullanarak sunucudan yeni bir eri\u015fim token&#8217;\u0131 talep eder. Refresh token&#8217;lar genellikle veritaban\u0131nda saklan\u0131r ve tek kullan\u0131ml\u0131k veya belli bir s\u00fcre sonra ge\u00e7ersiz k\u0131l\u0131nabilir olacak \u015fekilde tasarlan\u0131r. Bu sayede, bir refresh token \u00e7al\u0131nsa bile, sunucu taraf\u0131ndan kolayca iptal edilebilir ve sistemin g\u00fcvenli\u011fi korunmu\u015f olur.<\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: Refresh token&#8217;lar\u0131 HTTP-only \u00e7erezlerde saklayarak XSS (Cross-Site Scripting) sald\u0131r\u0131lar\u0131na kar\u015f\u0131 daha diren\u00e7li hale getirebilirsiniz. Eri\u015fim token&#8217;\u0131n\u0131 ise JavaScript ile eri\u015filebilecek bir yerde (\u00f6rne\u011fin, Local Storage) saklay\u0131p her API iste\u011finde &#8220;Authorization&#8221; ba\u015fl\u0131\u011f\u0131na ekleyebilirsiniz.\n    <\/div>\n<h3>Token S\u00fcreleri (Expiration) ve G\u00fcvenli Saklama Y\u00f6ntemleri<\/h3>\n<p>JWT&#8217;lerin son kullanma s\u00fcreleri (<code>exp<\/code> claim), g\u00fcvenlik a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir. Eri\u015fim token&#8217;lar\u0131 i\u00e7in k\u0131sa s\u00fcreler (15-60 dakika) tercih edilmelidir. Refresh token&#8217;lar\u0131 i\u00e7in ise daha uzun s\u00fcreler (g\u00fcnler, haftalar) kullan\u0131labilir, ancak bunlar da gerekti\u011finde iptal edilebilecek \u015fekilde tasarlanmal\u0131d\u0131r. Token&#8217;lar\u0131n g\u00fcvenli bir \u015fekilde saklanmas\u0131 da hayati \u00f6nem ta\u015f\u0131r:<\/p>\n<ul>\n<li><strong>HTTP-only Cookies:<\/strong> Refresh token&#8217;lar\u0131 saklamak i\u00e7in idealdir. JavaScript taraf\u0131ndan eri\u015filemezler, bu da XSS sald\u0131r\u0131lar\u0131na kar\u015f\u0131 koruma sa\u011flar. <code>Secure<\/code> bayra\u011f\u0131 ile sadece HTTPS \u00fczerinden g\u00f6nderilmelerini sa\u011flay\u0131n.<\/li>\n<li><strong>Local Storage vs. Session Storage:<\/strong> Eri\u015fim token&#8217;lar\u0131 i\u00e7in kullan\u0131labilir, ancak XSS sald\u0131r\u0131lar\u0131na kar\u015f\u0131 savunmas\u0131zd\u0131rlar. E\u011fer Local Storage kullan\u0131l\u0131yorsa, uygulaman\u0131z\u0131n XSS&#8217;e kar\u015f\u0131 \u00e7ok iyi korunmu\u015f oldu\u011fundan emin olun.<\/li>\n<li><strong>Bellek \u0130\u00e7i Saklama:<\/strong> SPA&#8217;lar ve mobil uygulamalar i\u00e7in, eri\u015fim token&#8217;\u0131n\u0131 uygulama belle\u011finde tutmak, sayfa yenilemede kaybolsa da, en g\u00fcvenli y\u00f6ntemlerden biridir.<\/li>\n<\/ul>\n<h3>Token \u0130ptali (Revocation) ve Kara Liste<\/h3>\n<p>JWT&#8217;ler do\u011falar\u0131 gere\u011fi &#8220;stateless&#8221; olduklar\u0131ndan, bir kez olu\u015fturulduktan sonra s\u00fcresi dolana kadar ge\u00e7erlidirler. Bu, bir kullan\u0131c\u0131n\u0131n \u015fifresini de\u011fi\u015ftirmesi veya hesab\u0131n\u0131n ask\u0131ya al\u0131nmas\u0131 durumunda bile, mevcut eri\u015fim token&#8217;lar\u0131n\u0131n s\u00fcresi dolana kadar ge\u00e7erli kalaca\u011f\u0131 anlam\u0131na gelir. Bu durumu y\u00f6netmek i\u00e7in &#8220;Kara Liste&#8221; (Blacklisting) veya &#8220;Beyaz Liste&#8221; (Whitelisting) gibi y\u00f6ntemler kullan\u0131labilir:<\/p>\n<ul>\n<li><strong>Kara Liste:<\/strong> \u0130ptal edilen token&#8217;lar\u0131 (\u00f6rne\u011fin, kullan\u0131c\u0131 \u00e7\u0131k\u0131\u015f yapt\u0131\u011f\u0131nda veya \u015fifre de\u011fi\u015ftirdi\u011finde) bir veritaban\u0131nda veya Redis gibi h\u0131zl\u0131 bir \u00f6nbellekte saklay\u0131n. Her istek geldi\u011finde, token&#8217;\u0131n kara listede olup olmad\u0131\u011f\u0131n\u0131 kontrol edin. Kara listedeki token&#8217;lar reddedilir.<\/li>\n<li><strong>Beyaz Liste:<\/strong> Yaln\u0131zca aktif refresh token&#8217;lar\u0131n\u0131 saklay\u0131n. Bir refresh token kullan\u0131ld\u0131\u011f\u0131nda, eski token&#8217;\u0131 ge\u00e7ersiz k\u0131l\u0131n ve yeni bir tane olu\u015fturun. Bu, her zaman ge\u00e7erli olan token&#8217;lar\u0131n bir kayd\u0131n\u0131 tutman\u0131za olanak tan\u0131r.<\/li>\n<\/ul>\n<p>Kara liste mekanizmas\u0131, \u00f6zellikle Redis gibi h\u0131zl\u0131 veri depolama \u00e7\u00f6z\u00fcmleriyle etkili bir \u015fekilde uygulanabilir. Token&#8217;\u0131n s\u00fcresi, kara listeye eklenirken Redis&#8217;teki ya\u015fam s\u00fcresi (TTL) olarak ayarlan\u0131r, b\u00f6ylece s\u00fcresi dolan token&#8217;lar otomatik olarak temizlenir.<\/p>\n<h3>Mobil Uygulamalar ve Tek Sayfal\u0131 Uygulamalar (SPA) \u0130\u00e7in JWT \u0130pu\u00e7lar\u0131<\/h3>\n<p>Mobil uygulamalar ve SPA&#8217;lar, JWT kullan\u0131m\u0131nda baz\u0131 \u00f6zel hususlara dikkat etmeyi gerektirir:<\/p>\n<ul>\n<li><strong>CORS (Cross-Origin Resource Sharing):<\/strong> Farkl\u0131 domain&#8217;lerden gelen istekleri kabul etmek i\u00e7in Express.js uygulaman\u0131zda CORS&#8217;u do\u011fru \u015fekilde yap\u0131land\u0131rmal\u0131s\u0131n\u0131z. <code>cors<\/code> npm paketi bu konuda size yard\u0131mc\u0131 olacakt\u0131r.<\/li>\n<li><strong>Yerel Depolama (Local Storage) vs. \u00c7erezler (Cookies):<\/strong> SPA&#8217;larda eri\u015fim token&#8217;lar\u0131n\u0131 Local Storage&#8217;da saklamak yayg\u0131n olsa da, XSS sald\u0131r\u0131lar\u0131na kar\u015f\u0131 daha savunmas\u0131zd\u0131r. HTTP-only \u00e7erezler bu riski azalt\u0131r ancak CSRF (Cross-Site Request Forgery) sald\u0131r\u0131lar\u0131na kar\u015f\u0131 ek \u00f6nlemler gerektirebilir (\u00f6rne\u011fin, CSRF token&#8217;lar\u0131). Mobil uygulamalarda ise token&#8217;lar genellikle uygulaman\u0131n g\u00fcvenli depolama alan\u0131nda saklan\u0131r.<\/li>\n<li><strong>HTTPS Kullan\u0131m\u0131:<\/strong> Her zaman HTTPS kullan\u0131n! JWT&#8217;ler \u015fifrelenmedi\u011fi i\u00e7in (sadece imzalan\u0131r), token&#8217;lar a\u011f \u00fczerinden d\u00fcz metin olarak iletilir. HTTPS, bu iletim s\u0131ras\u0131nda token&#8217;\u0131n dinlenmesini (eavesdropping) \u00f6nler.<\/li>\n<\/ul>\n<p>Mobil uyumluluk i\u00e7in, API&#8217;nizin yan\u0131tlar\u0131n\u0131n farkl\u0131 ekran boyutlar\u0131nda sorunsuz \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamak, istemci taraf\u0131 uygulaman\u0131n sorumlulu\u011fundad\u0131r. Ancak, genel web geli\u015ftirme prensiplerinde, duyarl\u0131 tasar\u0131mlar i\u00e7in CSS media query&#8217;leri kullan\u0131l\u0131r. \u00d6rne\u011fin, bir HTML sayfas\u0131nda a\u015fa\u011f\u0131daki gibi bir yap\u0131, farkl\u0131 cihazlar i\u00e7in farkl\u0131 stiller uygulayabilir:<\/p>\n<pre><code class=\"language-html\">\n&lt;!-- index.html --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html lang=\"tr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Mobil Uyumlu Sayfa&lt;\/title&gt;\n    &lt;style&gt;\n        body { font-family: Arial, sans-serif; }\n        .container { width: 90%; margin: 0 auto; }\n\n        @media (min-width: 768px) {\n            .container { width: 70%; }\n        }\n\n        @media (min-width: 1024px) {\n            .container { width: 50%; }\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"container\"&gt;\n        &lt;h1&gt;Responsive Tasar\u0131m \u00d6rne\u011fi&lt;\/h1&gt;\n        &lt;p&gt;Bu metin, ekran boyutuna g\u00f6re farkl\u0131 geni\u015fliklerde g\u00f6r\u00fcnecektir.&lt;\/p&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n    <\/code><\/pre>\n<p>Bu, do\u011frudan JWT ile ilgili olmasa da, modern web uygulamalar\u0131n\u0131n genelinde mobil uyumlulu\u011fun nas\u0131l sa\u011fland\u0131\u011f\u0131na dair bir \u00f6rnek te\u015fkil eder ve API&#8217;nizin t\u00fcketildi\u011fi istemci taraf\u0131nda bu t\u00fcr d\u00fc\u015f\u00fcncelerin \u00f6nemini vurgular.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Express.js uygulamalar\u0131n\u0131zda JSON Web Token (JWT) kullanmak, API&#8217;leriniz i\u00e7in g\u00fc\u00e7l\u00fc, \u00f6l\u00e7eklenebilir ve durum bilgisi tutmayan bir kimlik do\u011frulama ve yetkilendirme \u00e7\u00f6z\u00fcm\u00fc sunar. Bu makalede, JWT&#8217;nin temel yap\u0131s\u0131ndan ba\u015flayarak, Express.js projenize nas\u0131l entegre edece\u011finizi, kimlik do\u011frulama ve yetkilendirme middleware&#8217;leri yazmay\u0131 ve hatta ger\u00e7ek d\u00fcnya senaryolar\u0131nda nas\u0131l kullanabilece\u011finizi ad\u0131m ad\u0131m ele ald\u0131k. Ayr\u0131ca, refresh token mekanizmalar\u0131, g\u00fcvenli saklama y\u00f6ntemleri ve token iptali gibi ileri d\u00fczey g\u00fcvenlik konular\u0131na de\u011finerek, uygulaman\u0131z\u0131n potansiyel g\u00fcvenlik a\u00e7\u0131klar\u0131na kar\u015f\u0131 daha diren\u00e7li olmas\u0131n\u0131 sa\u011flama yollar\u0131n\u0131 inceledik. Do\u011fru stratejilerle uyguland\u0131\u011f\u0131nda, JWT&#8217;ler modern web uygulamalar\u0131n\u0131n omurgas\u0131n\u0131 olu\u015fturan API&#8217;ler i\u00e7in vazge\u00e7ilmez bir ara\u00e7 haline gelir.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<table border=\"1\">\n<thead>\n<tr>\n<th>Soru<\/th>\n<th>Cevap<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>JWT&#8217;ler \u015fifrelenir mi?<\/td>\n<td>Hay\u0131r, JWT&#8217;ler varsay\u0131lan olarak \u015fifrelenmez; sadece Base64url ile kodlan\u0131r ve imzalan\u0131r. Bu, i\u00e7eri\u011finin herkes taraf\u0131ndan okunabilece\u011fi anlam\u0131na gelir. Bu nedenle hassas bilgileri (\u00f6rne\u011fin, \u015fifreler) payload&#8217;a koymaktan ka\u00e7\u0131nmal\u0131s\u0131n\u0131z. \u0130mza, i\u00e7eri\u011fin de\u011fi\u015ftirilip de\u011fi\u015ftirilmedi\u011fini do\u011frulamak i\u00e7in kullan\u0131l\u0131r, gizlili\u011fi sa\u011flamak i\u00e7in de\u011fil.<\/td>\n<\/tr>\n<tr>\n<td>Refresh token&#8217;lar neden gereklidir?<\/td>\n<td>Refresh token&#8217;lar, k\u0131sa \u00f6m\u00fcrl\u00fc eri\u015fim token&#8217;lar\u0131n\u0131n s\u00fcresi doldu\u011funda kullan\u0131c\u0131n\u0131n tekrar giri\u015f yapmas\u0131na gerek kalmadan yeni bir eri\u015fim token&#8217;\u0131 almas\u0131n\u0131 sa\u011flar. Bu, hem kullan\u0131c\u0131 deneyimini iyile\u015ftirir hem de eri\u015fim token&#8217;lar\u0131n\u0131n \u00e7al\u0131nmas\u0131 durumunda sald\u0131rgan\u0131n eri\u015fim s\u00fcresini k\u0131s\u0131tlayarak g\u00fcvenli\u011fi art\u0131r\u0131r.<\/td>\n<\/tr>\n<tr>\n<td>JWT&#8217;leri Local Storage&#8217;da saklamak g\u00fcvenli midir?<\/td>\n<td>Local Storage&#8217;da JWT saklamak, XSS (Cross-Site Scripting) sald\u0131r\u0131lar\u0131na kar\u015f\u0131 savunmas\u0131zd\u0131r. K\u00f6t\u00fc niyetli bir JavaScript kodu, Local Storage&#8217;daki token&#8217;a eri\u015febilir ve onu \u00e7alabilir. Daha g\u00fcvenli bir alternatif, token&#8217;lar\u0131 HTTP-only ve Secure bayrakl\u0131 \u00e7erezlerde saklamakt\u0131r, ancak bu da CSRF (Cross-Site Request Forgery) sald\u0131r\u0131lar\u0131na kar\u015f\u0131 \u00f6nlemler gerektirir.<\/td>\n<\/tr>\n<tr>\n<td>JWT&#8217;yi nas\u0131l iptal edebilirim (revoke)?<\/td>\n<td>JWT&#8217;ler &#8220;stateless&#8221; olduklar\u0131ndan, do\u011frudan iptal edilemezler. Ancak, bir &#8220;kara liste&#8221; mekanizmas\u0131 uygulayarak iptal edebilirsiniz. Bu y\u00f6ntemde, iptal etmek istedi\u011finiz token&#8217;lar\u0131 bir veritaban\u0131na veya Redis gibi h\u0131zl\u0131 bir \u00f6nbelle\u011fe kaydedersiniz. Her istek geldi\u011finde, token&#8217;\u0131n kara listede olup olmad\u0131\u011f\u0131n\u0131 kontrol eder ve listedeyse reddedersiniz.<\/td>\n<\/tr>\n<tr>\n<td>JWT payload&#8217;\u0131na hangi bilgileri koymal\u0131y\u0131m?<\/td>\n<td>Payload&#8217;a, kullan\u0131c\u0131n\u0131n kimli\u011fini ve yetkilendirme i\u00e7in gerekli minimum bilgileri (\u00f6rne\u011fin, kullan\u0131c\u0131 ID&#8217;si, rolleri, kullan\u0131c\u0131 ad\u0131) koymal\u0131s\u0131n\u0131z. Hassas ki\u015fisel bilgileri veya \u00e7ok b\u00fcy\u00fck veri setlerini payload&#8217;a koymaktan ka\u00e7\u0131n\u0131n, \u00e7\u00fcnk\u00fc token boyutu artar ve a\u011f trafi\u011fini yava\u015flat\u0131r. Unutmay\u0131n, payload \u015fifrelenmedi\u011fi i\u00e7in herkes taraf\u0131ndan okunabilir.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Express.js&#8217;te JWT Kullan\u0131m\u0131: G\u00fcvenli Kimlik Do\u011frulama Rehberi Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-34629","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?<\/title>\n<meta name=\"description\" content=\"Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT&#039;yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API&#039;lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?\" \/>\n<meta property=\"og:description\" content=\"Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT&#039;yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API&#039;lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-19T21:20:47+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?\",\"datePublished\":\"2025-11-19T21:20:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\"},\"wordCount\":3053,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\",\"name\":\"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-19T21:20:47+00:00\",\"description\":\"Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT'yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API'lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?","description":"Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT'yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API'lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/","og_locale":"tr_TR","og_type":"article","og_title":"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?","og_description":"Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT'yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API'lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.","og_url":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-19T21:20:47+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"20 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?","datePublished":"2025-11-19T21:20:47+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/"},"wordCount":3053,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/","url":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/","name":"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-19T21:20:47+00:00","description":"Modern web uygulamalar\u0131 geli\u015ftirirken, kullan\u0131c\u0131 kimlik do\u011frulamas\u0131 ve yetkilendirmesi, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, sunucu taraf\u0131nda oturum bilgisi tutmadan, \u00f6l\u00e7eklenebilir ve g\u00fcvenli bir kimlik do\u011frulama sistemi nas\u0131l kurulur? JSON Web Token (JWT) bu soruna \u015f\u0131k ve etkili bir \u00e7\u00f6z\u00fcm sunar. Bu makalede, Express.js tabanl\u0131 uygulamalar\u0131n\u0131zda JWT'yi ad\u0131m ad\u0131m nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131, temel kavramlardan ileri d\u00fczey g\u00fcvenlik stratejilerine kadar t\u00fcm detaylar\u0131yla ke\u015ffedece\u011fiz. Art\u0131k API'lerinizin g\u00fcvenli\u011fini sa\u011flamak i\u00e7in haz\u0131rs\u0131n\u0131z.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/json-web-token-jwt-nedir-ve-neden-onemlidir\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"JSON Web Token (JWT) Nedir ve Neden \u00d6nemlidir?"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34629","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=34629"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34629\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=34629"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=34629"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=34629"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}