JAMstack Sitelerine Dinamik ve Zaman Uyumsuz İşlevsellik Ekleme
Yayınlanan: 2022-03-10Bu, JAMstack sitelerinin dinamik etkileşimleri kaldıramayacağı anlamına mı geliyor? Kesinlikle hayır!
JAMstack siteleri, son derece dinamik, eşzamansız etkileşimler oluşturmak için mükemmeldir. Kodumuz hakkında nasıl düşündüğümüzde bazı küçük ayarlamalar yaparak, yalnızca statik varlıkları kullanarak eğlenceli, sürükleyici etkileşimler oluşturabiliriz!
JAMstack kullanılarak oluşturulmuş web sitelerini, yani JavaScript, İşaretleme ve API'lerden oluşturulmuş statik HTML dosyaları olarak sunulabilen web sitelerini görmek giderek daha yaygın hale geliyor. Şirketler JAMstack'i seviyor çünkü altyapı maliyetlerini düşürüyor, teslimatı hızlandırıyor ve performans ve güvenlik iyileştirmelerinin önündeki engelleri azaltıyor, çünkü statik varlıkların gönderilmesi sunucuları ölçeklendirme veya veritabanlarını yüksek düzeyde kullanılabilir tutma ihtiyacını ortadan kaldırıyor (bu da sunucuların veya veritabanlarının olmadığı anlamına geliyor). saldırıya uğramak). Geliştiriciler JAMstack'i sever çünkü bir web sitesini internette yayınlamanın karmaşıklığını azaltır: yönetilecek veya dağıtılacak sunucu yoktur; ön uç kodu yazabiliriz ve sihir gibi canlı yayına geçer .
(“Bu durumda sihir”, çalıştığım yer olan Netlify dahil olmak üzere bir dizi şirketten ücretsiz olarak sağlanan otomatikleştirilmiş statik dağıtımlardır.)
Ancak geliştiricilerle JAMstack hakkında konuşmak için çok zaman harcarsanız, JAMstack'in Ciddi Web Uygulamalarını işleyip işleyemeyeceği sorusu ortaya çıkacaktır. Sonuçta, JAMstack siteleri statik sitelerdir, değil mi? Ve statik sitelerin yapabilecekleri çok sınırlı değil mi?
Bu gerçekten yaygın bir yanlış anlamadır ve bu makalede, yanlış anlamanın nereden geldiğine dalacağız, JAMstack'in yeteneklerine bakacağız ve Ciddi Web Uygulamaları oluşturmak için JAMstack'i kullanmanın birkaç örneğini gözden geçireceğiz.
JAMstack Temelleri
Phil Hawksworth, JAMStack'in gerçekte ne anlama geldiğini ve projelerinizde kullanmanın ne zaman mantıklı olduğunu ve bunun takım oluşturma ve ön uç mimarisini nasıl etkilediğini açıklıyor. İlgili bir makaleyi okuyun →
Bir JAMstack Sitesini “Statik” Yapan Nedir?
Bugün web tarayıcıları, tıpkı 90'larda olduğu gibi HTML, CSS ve JavaScript dosyaları yüklüyor.
Bir JAMstack sitesi özünde HTML, CSS ve JavaScript dosyalarıyla dolu bir klasördür.
Bunlar “statik varlıklardır”, yani onları oluşturmak için bir ara adıma ihtiyacımız yoktur (örneğin, WordPress gibi PHP projelerinin her istekte HTML'yi oluşturmak için bir sunucuya ihtiyacı vardır).
JAMstack'in gerçek gücü budur: çalışması için herhangi bir özel altyapı gerektirmez. JAMstack sitesini yerel bilgisayarınızda, tercih ettiğiniz içerik dağıtım ağına (CDN) koyarak ve GitHub Pages gibi hizmetlerle barındırarak çalıştırabilirsiniz - hatta klasörü yüklemek için favori FTP istemcinize sürükleyip bırakabilirsiniz. paylaşılan barındırma için.
Statik Varlıklar Mutlaka Statik Deneyimler anlamına gelmez
JAMstack siteleri statik dosyalardan oluştuğu için, bu sitelerdeki deneyimin, bilirsiniz, statik olduğunu varsaymak kolaydır. Ama durum böyle değil!
JavaScript, bir sürü dinamik şey yapabilir. Ne de olsa, modern JavaScript çerçeveleri, oluşturma adımını geçtikten sonra statik dosyalardır ve bunlar tarafından desteklenen yüzlerce inanılmaz dinamik web sitesi deneyimi örneği vardır.
“Statik” in esnek olmayan veya sabit anlamına geldiğine dair yaygın bir yanlış anlama vardır. Ancak, "statik siteler" bağlamında tüm bu "statik"in anlamı, tarayıcıların içeriklerini teslim etmek için herhangi bir yardıma ihtiyaç duymadıklarıdır - önce bir işlem adımını ele alan bir sunucu olmadan bunları yerel olarak kullanabilirler.
Veya başka bir şekilde koyun:
"Statik varlıklar", statik uygulamalar anlamına gelmez; sunucuya gerek olmadığı anlamına gelir.
“
JAMstack Bunu Yapabilir mi?
Birisi yeni bir uygulama oluşturma hakkında soru sorarsa, Gatsby, Eleventy, Nuxt ve diğer benzer araçlar gibi JAMstack yaklaşımları için öneriler görmek yaygındır. İtirazların ortaya çıktığını görmek de aynı derecede yaygındır: “statik site oluşturucular _______ yapamaz”, burada ______ dinamik bir şeydir.
Ancak - önceki bölümde değindiğimiz gibi - JAMstack siteleri dinamik içerik ve etkileşimleri işleyebilir !
İnsanların JAMstack'in kesinlikle yapamayacağını iddia ettiğini defalarca duyduğum eksik bir liste:
- Verileri eşzamansız olarak yükle
- Görüntüleri işlemek gibi dosyaları işlemek
- Veritabanından okuma ve veritabanına yazma
- Kullanıcı kimlik doğrulamasını yönetin ve bir oturum açma işleminin arkasındaki içeriği koruyun
Aşağıdaki bölümlerde, bu iş akışlarının her birinin bir JAMstack sitesinde nasıl uygulanacağına bakacağız.
Dinamik JAMstack'i çalışırken görmek için sabırsızlanıyorsanız, önce demolara göz atabilir, ardından geri gelip nasıl çalıştıklarını öğrenebilirsiniz.
Demolar hakkında bir not :
Bu demolar herhangi bir çerçeve olmadan yazılmıştır. Bunlar yalnızca HTML, CSS ve standart JavaScript'tir. Modern tarayıcılar (ör. Chrome, Firefox, Safari, Edge) düşünülerek oluşturulmuştur ve JavaScript modülleri, HTML şablonları ve Fetch API gibi daha yeni özelliklerden yararlanır. Çoklu dolgu eklenmedi, bu nedenle desteklenmeyen bir tarayıcı kullanıyorsanız demolar muhtemelen başarısız olacaktır.
Üçüncü Taraf API'sinden Zaman Uyumsuz Olarak Veri Yükleme
"Statik dosyalarım oluşturulduktan sonra yeni veriler almam gerekirse ne olur?"
JAMstack'te, herhangi bir noktada JavaScript kullanarak veri yüklemek için yerleşik Fetch API dahil olmak üzere çok sayıda eşzamansız istek kitaplığından yararlanabiliriz.
Demo: Bir JAMstack Sitesinden Üçüncü Taraf Bir API Arayın
Eşzamansız yükleme gerektiren yaygın bir senaryo, ihtiyacımız olan içeriğin kullanıcı girdisine bağlı olmasıdır. Örneğin, Rick & Morty API için bir arama sayfası oluşturursak, birisi bir arama terimi girene kadar hangi içeriğin görüntüleneceğini bilemeyiz.
Bununla başa çıkmak için yapmamız gerekenler:
- İnsanların arama terimlerini yazabilecekleri bir form oluşturun,
- Form gönderimini dinleyin,
- Form gönderiminden arama terimini alın,
- Arama terimini kullanarak Rick & Morty API'sine eşzamansız bir istek gönderin,
- İstek sonuçlarını sayfada görüntüleyin.
İlk olarak, şuna benzeyen arama sonuçlarımızı içerecek bir form ve boş bir öğe oluşturmamız gerekiyor:
<form> <label for="name">Find characters by name</label> <input type="text" name="name" required /> <button type="submit">Search</button> </form> <ul></ul>
Ardından, form gönderimlerini işleyen bir işlev yazmamız gerekiyor. Bu işlev:
- Varsayılan form gönderme davranışını engelle
- Arama terimini form girişinden alın
- Arama terimini kullanarak Rick & Morty API'sine bir istek göndermek için Getir API'sini kullanın
- Arama sonuçlarını sayfada görüntüleyen bir yardımcı işlevi çağırın
Ayrıca, işleyici işlevimizi çağıran gönderme olayı için forma bir olay dinleyicisi eklememiz gerekiyor.
İşte bu kod tamamen neye benziyor:
<script type="module"> import showResults from './show-results.js'; const form = document.querySelector('form'); const handleSubmit = async event => { event.preventDefault(); // get the search term from the form input const name = form.elements['name'].value; // send a request to the Rick & Morty API based on the user input const characters = await fetch( `https://rickandmortyapi.com/api/character/?name=${name}`, ) .then(response => response.json()) .catch(error => console.error(error)); // add the search results to the DOM showResults(characters.results); }; form.addEventListener('submit', handleSubmit); </script>
Not: Dinamik JAMstack davranışlarına odaklanmak için, showResults gibi yardımcı fonksiyonların nasıl yazıldığını tartışmayacağız. Yine de kod tamamen yorumlanmıştır, bu yüzden nasıl çalıştığını öğrenmek için kaynağa bakın!
Bu kod yerindeyken sitemizi bir tarayıcıya yükleyebiliriz ve boş formu hiçbir sonuç göstermeden göreceğiz:

Bir karakter adı girersek (örn. “rick”) ve “ara”ya tıklarsak, adlarında “rick” bulunan karakterlerin bir listesinin görüntülendiğini görürüz:

Hey! Bu statik site sadece dinamik olarak veri mi yükledi? Kutsal kovalar!
Bunu canlı demoda kendiniz deneyebilir veya daha fazla ayrıntı için tam kaynak koduna göz atabilirsiniz.
Pahalı Bilgi İşlem Görevlerini Kullanıcının Aygıtından Çıkarın
Birçok uygulamada, bir görüntüyü işlemek gibi oldukça kaynak yoğun şeyler yapmamız gerekir. Bu tür işlemlerden bazıları yalnızca istemci tarafı JavaScript kullanılarak mümkün olsa da, tüm bunları kullanıcılarınızın cihazlarının yapmasını sağlamak iyi bir fikir değildir. Düşük güçlü bir cihaz kullanıyorlarsa veya pil ömrünün son %5'ini uzatmaya çalışıyorlarsa, cihazlarının bir sürü iş yapmasını sağlamak muhtemelen onlar için sinir bozucu bir deneyim olacaktır.
Bu, JAMstack uygulamalarının şanssız olduğu anlamına mı geliyor? Hiç de bile!
JAMstack'teki "A", API'ler anlamına gelir. Bu, bu çalışmayı bir API'ye gönderebileceğimiz ve kullanıcılarımızın bilgisayar fanlarını "vurgulu" ayarına döndürmekten kaçınabileceğimiz anlamına gelir.
"Ama bekle" diyebilirsiniz. "Uygulamamızın özel bir çalışma yapması gerekiyorsa ve bu iş bir API gerektiriyorsa, bu sadece bir sunucu inşa ettiğimiz anlamına gelmez mi?"
Sunucusuz işlevlerin gücü sayesinde, buna ihtiyacımız yok!
Sunucusuz işlevler ("lambda işlevleri" olarak da adlandırılır), herhangi bir sunucu ortak plakası gerektirmeyen bir tür API'dir. Düz, eski bir JavaScript işlevi yazıyoruz ve tüm dağıtım, ölçeklendirme, yönlendirme ve benzeri işler, sunucusuz seçim sağlayıcımıza aktarılıyor.
Sunucusuz işlevlerin kullanılması, sunucu olmadığı anlamına gelmez; bu sadece bir sunucu hakkında düşünmemize gerek olmadığı anlamına gelir.
“
Sunucusuz işlevler, JAMstack'imizin fıstık ezmesidir: bizden sunucu kodu veya devop'larla uğraşmamızı istemeden, yüksek güçlü, dinamik işlevsellik dünyasının kilidini açarlar.
Demo: Bir Resmi Gri Tonlamaya Dönüştür
Şunları yapması gereken bir uygulamamız olduğunu varsayalım:
- Bir URL'den bir resim indirin
- Bu görüntüyü gri tonlamaya dönüştürün
- Dönüştürülen görüntüyü GitHub deposuna yükleyin
Bildiğim kadarıyla, tamamen tarayıcıda böyle görüntü dönüştürmeleri yapmanın bir yolu yok - ve olsa bile, yapılacak oldukça kaynak yoğun bir şey, bu yüzden muhtemelen bu yükü kullanıcılarımıza yüklemek istemiyoruz ' cihazlar.
Bunun yerine, URL'yi sunucusuz bir işleve dönüştürülecek şekilde gönderebiliriz; bu, bizim için ağır yükü kaldıracak ve dönüştürülmüş bir görüntüye bir URL'yi geri gönderecektir.
Sunucusuz işlevimiz için Netlify İşlevlerini kullanacağız. Sitemizin koduna "functions" isimli kök seviyesinde bir klasör ekliyoruz ve içinde "convert-image.js" isimli yeni bir dosya oluşturuyoruz. Ardından, işleyici denilen şeyi yazarız; bu, alır ve - tahmin edebileceğiniz gibi - sunucusuz işlevimize yönelik istekleri işler .
Bir görüntüyü dönüştürmek için şöyle görünür:
exports.handler = async event => { // only try to handle POST requests if (event.httpMethod !== 'POST') { return { statusCode: 404, body: '404 Not Found' }; } try { // get the image URL from the POST submission const { imageURL } = JSON.parse(event.body); // use a temporary directory to avoid intermediate file cruft // see https://www.npmjs.com/package/tmp const tmpDir = tmp.dirSync(); const convertedPath = await convertToGrayscale(imageURL, tmpDir); // upload the processed image to GitHub const response = await uploadToGitHub(convertedPath, tmpDir.name); return { statusCode: 200, body: JSON.stringify({ url: response.data.content.download_url, }), }; } catch (error) { return { statusCode: 500, body: JSON.stringify(error.message), }; } };
Bu işlev aşağıdakileri yapar:
- İsteğin HTTP POST yöntemi kullanılarak gönderildiğinden emin olmak için kontrol eder
- POST gövdesinden resim URL'sini alır
- İşlev yürütüldüğünde temizlenecek dosyaları depolamak için geçici bir dizin oluşturur.
- Görüntüyü gri tonlamaya dönüştüren bir yardımcı işlevi çağırır
- Dönüştürülen görüntüyü GitHub'a yükleyen bir yardımcı işlevi çağırır
- HTTP 200 durum kodu ve yeni yüklenen görüntünün URL'si ile bir yanıt nesnesi döndürür
Not : Resim dönüştürme veya GitHub'a yükleme için yardımcı işlevlerin nasıl çalıştığının üzerinde durmayacağız, ancak nasıl çalıştığını görebilmeniz için kaynak kodu iyi yorumlanmıştır.
Ardından, URL'leri işlenmek üzere göndermek için kullanılacak bir form ve öncesi ve sonrasının gösterileceği bir yer eklememiz gerekiyor:
<form action="/.netlify/functions/convert-image" method="POST" > <label for="imageURL">URL of an image to convert</label> <input type="url" name="imageURL" required /> <button type="submit">Convert</button> </form> <div></div>
Son olarak, URL'leri işlenmek üzere sunucusuz işlevimize gönderebilmemiz için forma bir olay dinleyicisi eklememiz gerekiyor:
<script type="module"> import showResults from './show-results.js'; const form = document.querySelector('form'); form.addEventListener('submit', event => { event.preventDefault(); // get the image URL from the form const imageURL = form.elements['imageURL'].value; // send the image off for processing const promise = fetch('/.netlify/functions/convert-image', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ imageURL }), }) .then(result => result.json()) .catch(error => console.error(error)); // do the work to show the result on the page showResults(imageURL, promise); }); </script>
Siteyi (yeni "fonksiyonlar" klasörüyle birlikte) Netlify'a dağıttıktan ve/veya Netlify Dev'i CLI'mizde başlattıktan sonra, formu tarayıcımızda görebiliriz:

Forma bir resim URL'si ekler ve “dönüştür”e tıklarsak, dönüştürme yapılırken bir an için “işleniyor…” ifadesini görürüz, ardından orijinal resmi ve yeni oluşturulan gri tonlamalı karşılığını görürüz:


Ah lanet! JAMstack sitemiz oldukça ciddi bir işin üstesinden geldi ve sunucuları bir kez düşünmek veya kullanıcılarımızın pillerini tüketmek zorunda kalmadık!
Girişleri Saklamak ve Almak İçin Bir Veritabanı Kullanın
Birçok uygulamada, kaçınılmaz olarak kullanıcı girdisini kaydetme yeteneğine ihtiyacımız olacak. Bu da bir veritabanına ihtiyacımız olduğu anlamına geliyor.
“Demek bu kadar, değil mi? Jig kalktı mı? Bize söylediğiniz bir JAMstack sitesi, bir klasördeki dosyalardan oluşan bir koleksiyon olduğundan kesinlikle bir veritabanına bağlanamaz!”
Aksi halde.
Önceki bölümde gördüğümüz gibi, sunucusuz işlevler bize kendi sunucularımızı oluşturmaya gerek kalmadan her türlü güçlü şeyi yapma yeteneği verir.
Benzer şekilde, bir veritabanını kurmak veya barındırmak zorunda kalmadan bir veritabanını okumak ve yazmak için hizmet olarak veritabanı (DBaaS) araçlarını (Fauna gibi) kullanabiliriz.
DBaaS araçları, web siteleri için veritabanları kurma sürecini büyük ölçüde basitleştirir: yeni bir veritabanı oluşturmak, depolamak istediğimiz veri türlerini tanımlamak kadar basittir. Araçlar, oluşturma, okuma, güncelleme ve silme (CRUD) işlemlerini yönetmek için tüm kodu otomatik olarak oluşturur ve API aracılığıyla kullanmamızı sağlar, böylece bir veritabanını gerçekten yönetmemiz gerekmez; biz sadece onu kullanırız .
Demo: Bir Dilekçe Sayfası Oluşturun
Bir dilekçe için dijital imza toplamak için küçük bir uygulama oluşturmak istiyorsak, bu imzaları depolamak ve sayfanın bunları görüntülemek için okumasına izin vermek için bir veritabanı kurmamız gerekir.
Bu demo için Fauna'yı DBaaS sağlayıcımız olarak kullanacağız. Fauna'nın nasıl çalıştığına derinlemesine girmeyeceğiz, ancak bir veritabanı kurmak için gereken az miktardaki çabayı göstermek adına, her adımı listeleyelim ve kullanıma hazır bir veritabanı almak için tıklayalım:
- https://fauna.com adresinde bir Fauna hesabı oluşturun
- "Yeni bir veritabanı oluştur" u tıklayın
- Veritabanına bir ad verin (örneğin “dinamik-sıkışma-demolar”)
- "Oluştur" u tıklayın
- Sonraki sayfada soldaki menüden “güvenlik”e tıklayın
- "Yeni anahtar" ı tıklayın
- Rol açılır menüsünü "Sunucu" olarak değiştirin
- Anahtar için bir ad ekleyin (örn. “Dinamik JAMstack Demoları”)
- Uygulamayla kullanmak için anahtarı güvenli bir yerde saklayın
- "kaydet"e tıklayın
- Soldaki menüden “GraphQL” seçeneğine tıklayın
- "Şemayı içe aktar" ı tıklayın
- Aşağıdaki kodu içeren
db-schema.gql
adlı bir dosya yükleyin:
type Signature { name: String! } type Query { signatures: [Signature!]! }
Şemayı yüklediğimizde veritabanımız kullanıma hazırdır. (Gerçekten.)
On üç adım çok fazla, ancak bu on üç adımda bir veritabanı, bir GraphQL API, otomatik kapasite yönetimi, ölçekleme, dağıtım, güvenlik ve daha fazlasını elde ettik - tümü veritabanı uzmanları tarafından ele alındı. Ücretsiz. Hayatta olmak için ne güzel bir zaman!
Denemek için, soldaki menüdeki “GraphQL” seçeneği, CRUD işlemlerini gerçekleştirmemize izin veren mevcut sorgular ve mutasyonlar hakkında belgeler içeren bir GraphQL gezgini sunar.
Not : Bu gönderide GraphQL sorguları ve mutasyonları hakkında ayrıntılara girmeyeceğiz, ancak Eve Porcello, nasıl çalıştığına dair bir başlangıç istiyorsanız GraphQL sorguları ve mutasyonları göndermek için mükemmel bir giriş yazdı.
Veritabanı kullanıma hazır olduğunda, veritabanında yeni imzaları depolayan sunucusuz bir işlev oluşturabiliriz:
const qs = require('querystring'); const graphql = require('./util/graphql'); exports.handler = async event => { try { // get the signature from the POST data const { signature } = qs.parse(event.body); const ADD_SIGNATURE = ` mutation($signature: String!) { createSignature(data: { name: $signature }) { _id } } `; // store the signature in the database await graphql(ADD_SIGNATURE, { signature }); // send people back to the petition page return { statusCode: 302, headers: { Location: '/03-store-data/', }, // body is unused in 3xx codes, but required in all function responses body: 'redirecting...', }; } catch (error) { return { statusCode: 500, body: JSON.stringify(error.message), }; } };
Bu işlev aşağıdakileri yapar:
- Form
POST
verisinden imza değerini alır - İmzayı veritabanında saklayan bir yardımcı işlevi çağırır
- Veritabanına yazmak için bir GraphQL mutasyonu tanımlar
- Bir GraphQL yardımcı işlevi kullanarak mutasyonu gönderir
- Verileri gönderen sayfaya geri yönlendirir
Ardından, dilekçemizi kaç kişinin desteklediğini gösterebilmemiz için veritabanındaki tüm imzaları okumak için sunucusuz bir işleve ihtiyacımız var:
const graphql = require('./util/graphql'); exports.handler = async () => { const { signatures } = await graphql(` query { signatures { data { name } } } `); return { statusCode: 200, body: JSON.stringify(signatures.data), }; };
Bu işlev bir sorgu gönderir ve onu döndürür.
Hassas anahtarlar ve JAMstack uygulamaları hakkında önemli bir not :
Bu uygulama hakkında not edilmesi gereken bir nokta, bu aramaları yapmak için sunucusuz işlevleri kullanmamızdır, çünkü Fauna'ya bu veritabanına okuma ve yazma erişimimiz olduğunu kanıtlayan özel bir sunucu anahtarı iletmemiz gerekir. Bu anahtarı istemci tarafı koduna koyamayız, çünkü bu, herkesin onu kaynak kodda bulabileceği ve veritabanımıza karşı CRUD işlemleri gerçekleştirmek için kullanabileceği anlamına gelir. Sunucusuz işlevler, JAMstack uygulamalarında özel anahtarları gizli tutmak için kritik öneme sahiptir.
Sunucusuz işlevlerimizi ayarladıktan sonra, imza ekleme işlevine gönderen bir form, mevcut imzaları göstermek için bir öğe ve işlevi çağırmak ve imzaları almak ve bunları ekranımıza koymak için biraz JS ekleyebiliriz. eleman:
<form action="/.netlify/functions/add-signature" method="POST"> <label for="signature">Your name</label> <input type="text" name="signature" required /> <button type="submit">Sign</button> </form> <ul class="signatures"></ul> <script> fetch('/.netlify/functions/get-signatures') .then(res => res.json()) .then(names => { const signatures = document.querySelector('.signatures'); names.forEach(({ name }) => { const li = document.createElement('li'); li.innerText = name; signatures.appendChild(li); }); }); </script>
Bunu tarayıcıya yüklersek, altında imzaları olan dilekçe formumuzu göreceğiz:

Ardından imzamızı eklersek…

…ve gönderin, adımızın listenin en altına eklendiğini göreceğiz:

Ateşli köpek! Az önce yaklaşık 75 satır kod ve 7 satır veritabanı şeması içeren, veritabanı destekli tam bir JAMstack uygulaması yazdık!
İçeriği Kullanıcı Kimlik Doğrulaması ile Koruyun
“Tamam, bu sefer kesinlikle sıkışıp kaldın” diye düşünüyor olabilirsiniz. “Bir JAMstack sitesinin kullanıcı kimlik doğrulamasını işlemesinin hiçbir yolu yoktur . Bu nasıl işe yarayacak ki?!"
Size nasıl çalıştığını anlatacağım dostum: güvenilir sunucusuz işlevlerimiz ve OAuth ile.
OAuth, insanların şifrelerini paylaşmak yerine uygulamalara hesap bilgilerine sınırlı erişim vermelerine izin vermek için yaygın olarak benimsenen bir standarttır. Daha önce başka bir hizmeti kullanarak bir hizmete giriş yaptıysanız (örneğin, "Google hesabınızla oturum açın"), daha önce OAuth kullanmışsınızdır.
Not: OAuth'un nasıl çalıştığına derinlemesine girmeyeceğiz, ancak Aaron Parecki, ayrıntıları ve iş akışını kapsayan OAuth'a sağlam bir genel bakış yazdı.
JAMstack uygulamalarında, kullanıcıları tanımlamak, içeriği korumak ve yalnızca oturum açmış kullanıcıların görüntülemesine izin vermek için bize sağladığı OAuth ve JSON Web Belirteçlerinden (JWT'ler) yararlanabiliriz.
Demo: Korumalı İçeriği Görüntülemek için Giriş Gerektirin
Yalnızca oturum açmış kullanıcılara içerik gösteren bir site oluşturmamız gerekiyorsa, birkaç şeye ihtiyacımız var:
- Kullanıcıları ve oturum açma akışını yöneten bir kimlik sağlayıcı
- Oturum açmayı ve oturumu kapatmayı yönetmek için UI öğeleri
- JWT'leri kullanarak oturum açmış bir kullanıcıyı kontrol eden ve sağlanmışsa korumalı içerik döndüren sunucusuz bir işlev
Bu örnek için, kimlik doğrulama eklemek için bize gerçekten hoş bir geliştirici deneyimi sunan ve oturum açma ve oturum kapatma işlemlerini yönetmek için bir açılır pencere öğesi sağlayan Netlify Identity'yi kullanacağız.
Etkinleştirmek için:
- Netlify kontrol panelinizi ziyaret edin
- Siteler listenizden yetkilendirme gerektiren siteyi seçin
- Üst gezinme panelindeki "kimlik" i tıklayın
- "Kimliği Etkinleştir" düğmesini tıklayın
Netlify Identity'yi, oturumu kapatılmış içeriği gösteren ve oturum açtıktan sonra korumalı içeriği göstermek için bir öğe ekleyen bir işaretleme ekleyerek sitemize ekleyebiliriz:
<div class="content logged-out"> <h1>Super Secret Stuff!</h1> <p> only my bestest friends can see this content</p> <button class="login">log in / sign up to be my best friend</button> </div> <div class="content logged-in"> <div class="secret-stuff"></div> <button class="logout">log out</button> </div>
Bu işaretleme, kullanıcının oturum açıp açmadığına bağlı olarak içeriği göstermek için CSS'ye dayanır. Ancak, içeriği gerçekten korumak için buna güvenemeyiz - herhangi biri kaynak kodunu görüntüleyebilir ve sırlarımızı çalabilir!
Bunun yerine, korunan içeriğimizi içerecek boş bir div oluşturduk, ancak bu içeriği gerçekten almak için sunucusuz bir işleve istekte bulunmamız gerekecek. Bunun nasıl çalıştığını birazdan inceleyeceğiz.
Ardından, oturum açma düğmemizin çalışması için kod eklememiz, korumalı içeriği yüklememiz ve ekranda göstermemiz gerekiyor:
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script> <script> const login = document.querySelector('.login'); login.addEventListener('click', () => { netlifyIdentity.open(); }); const logout = document.querySelector('.logout'); logout.addEventListener('click', () => { netlifyIdentity.logout(); }); netlifyIdentity.on('logout', () => { document.querySelector('body').classList.remove('authenticated'); }); netlifyIdentity.on('login', async () => { document.querySelector('body').classList.add('authenticated'); const token = await netlifyIdentity.currentUser().jwt(); const response = await fetch('/.netlify/functions/get-secret-content', { headers: { Authorization: `Bearer ${token}`, }, }).then(res => res.text()); document.querySelector('.secret-stuff').innerHTML = response; }); </script>
İşte bu kodun yaptığı:
- Bir oturum açma modu oluşturan bir yardımcı kitaplık olan Netlify Identity pencere aracını yükler, Netlify Identity ile OAuth iş akışını yönetir ve uygulamamızın oturum açmış kullanıcının bilgilerine erişmesini sağlar
- Netlify Identity oturum açma modunun açılmasını tetikleyen oturum açma düğmesine bir olay dinleyicisi ekler
- Netlify Identity oturum kapatma yöntemini çağıran çıkış düğmesine bir olay dinleyicisi ekler
- Oturum kapatıldığında kimliği doğrulanmış sınıfı kaldırmak için oturumu kapatmak için oturum açmış içeriği gizleyen ve oturum kapatılmış içeriği gösteren bir olay işleyicisi ekler
- Giriş yapmak için bir olay işleyicisi ekler:
- Oturum açmış içeriği göstermek ve çıkış yapılmış içeriği gizlemek için kimliği doğrulanmış sınıfı ekler
- Oturum açmış kullanıcının JWT'sini alır
- JWT'yi Yetkilendirme başlığına göndererek korumalı içeriği yüklemek için sunucusuz bir işlevi çağırır
- Gizli içeriği, oturum açmış kullanıcıların görebilmesi için gizli içerik div'ine koyar
Şu anda bu kodda çağırdığımız sunucusuz işlev mevcut değil. Aşağıdaki kod ile oluşturalım:
exports.handler = async (_event, context) => { try { const { user } = context.clientContext; if (!user) throw new Error('Not Authorized'); return { statusCode: 200, headers: { 'Content-Type': 'text/html', }, body: `
Davetlisiniz, ${user.user_metadata.full_name}!
Bunu okuyabiliyorsan, en iyi arkadaşız demektir.
İşte doğum günü partimin gizli detayları:
`, }; } yakalama (hata) { dönüş { durumKodu: 401, gövde: 'Yetkili Değil', }; } };
jason.af/party
Bu işlev aşağıdakileri yapar:
- Sunucusuz işlevin bağlam bağımsız değişkeninde bir kullanıcı olup olmadığını kontrol eder
- Kullanıcı bulunamazsa hata verir
- Oturum açmış bir kullanıcının talep ettiğinden emin olduktan sonra gizli içeriği döndürür
Netlify Functions, Yetkilendirme başlıklarında Netlify Identity JWT'lerini algılar ve bu bilgileri otomatik olarak bağlama koyar - bu, JWT'leri doğrulamak için kod yazmaya gerek kalmadan geçerli bir JWT'leri kontrol edebileceğimiz anlamına gelir!
Bu sayfayı tarayıcımıza yüklediğimizde, önce çıkış sayfasını göreceğiz:

Giriş yapmak için düğmeye tıklarsak, Netlify Identity widget'ını göreceğiz:

Giriş yaptıktan (veya kaydolduktan) sonra korunan içeriği görebiliriz:

Vay canına! Az önce bir JAMstack uygulamasına kullanıcı girişi ve korumalı içerik ekledik!
Sonra ne yapacağız
JAMstack, "sadece statik sitelerden" çok daha fazlasıdır - kullanıcı etkileşimlerine yanıt verebilir, veri depolayabilir, kullanıcı kimlik doğrulamasını işleyebilir ve modern bir web sitesinde yapmak istediğimiz hemen hemen her şeyi yapabiliriz. Üstelik bir sunucu sağlamaya, yapılandırmaya veya dağıtmaya gerek kalmadan!
JAMstack ile ne inşa etmek istiyorsunuz? JAMstack'in halledebileceğine hala ikna olmadığınız bir şey var mı? Bunu duymayı çok isterim - Twitter'da veya yorumlarda bana ulaşın!