16. [nuxt-13] örneği: [nuxt-12]'in gezinme yapısının kontrolü
Bu örnekte, [nuxt-12] sayfasının gezinme yapısına odaklanıyoruz. [nuxt-12] sayfasında bunu yapmadık, çünkü gezinme yapısının kontrolü zaten karmaşık olan bir örneği daha da karmaşık hale getirecekti.
Amaç: Kullanıcının yalnızca izin verilen eylemleri gerçekleştirebilmesini sağlamak istiyoruz:
- jSON oturumu başlamamışsa, yalnızca URL ve [/] işlemlerine izin verilir;
- jSON oturumu başlatılmışsa ancak kullanıcı kimliği doğrulanmamışsa, yalnızca URL ve [/authentification] oturumları izin verilir;
- jSON oturumu başlatılmışsa ve kullanıcı kimliği doğrulanmışsa, yalnızca URL ve [/get-admindata, /fin-session] oturumlarına izin verilir;
- o anki yönlendirme hedefi izin verilmiyorsa, izin verilen bir URL'e yönlendirme yapılır;
[nuxt-13] örneği, başlangıçta [nuxt-12] örneğinin kopyalanmasıyla elde edilir:

Değişiklikler, [middleware] yönlendirme klasöründe gerçekleştirilecektir.
16.1. [nuxt] uygulamasının yönlendirmesi
Uygulama yönlendirmesi, [nuxt.config] dosyasında şu şekilde yapılandırılmıştır:
// yönlendirici
router: {
// uygulamanın URL kökü
base: '/nuxt-13/',
// yönlendirme ara yazılımı
middleware: ['routing']
},
- 6. satır: Uygulama yönlendirmesi, [middleware/routing] dosyası tarafından kontrol edilir;
[middleware/routing] dosyası şu şekildedir:
/* eslint-disable no-console */
// sunucu ve istemci ara yazılımlarını içe aktarıyoruz
import serverRouting from './server/routing'
import clientRouting from './client/routing'
export default function(context) {
// Bu kodu kim çalıştırıyor?
console.log('[middleware], process.server', process.server, ', process.client=', process.client)
if (process.server) {
// sunucu yönlendirmesi
serverRouting(context)
} else {
// istemci yönlendirmesi
clientRouting(context)
}
}
- 10-16. satırlar: İstemci ve sunucu yönlendirmeleri farklı şekilde işlenir ([nuxt]). Bu, ikisi arasında büyük bir farkın olduğu bir noktadır;
- 4. satır: Sunucu yönlendirmesi, [middleware/server/routing] komut dosyası ile gerçekleştirilir;
- satır 5: İstemci yönlendirmesi, [middleware/client/routing] komut dosyası ile gerçekleştirilir;
16.2. [nuxt] istemci yönlendirmesi
[nuxt] istemci yönlendirmesi, [nuxt-12]'teki haliyle kalır:
/* eslint-disable no-console */
export default function(context) {
// Bu kodu kim çalıştırıyor?
console.log('[middleware client], process.server', process.server, ', process.client=', process.client)
// tarayıcıdaki PHP oturum çerezinin yönetimi
// Tarayıcıdaki PHP oturum çerezi, Nuxt oturumunda bulunanla aynı olmalıdır
// [fin-session] eylemi, yeni bir PHP çerezi alır (hem sunucu hem de Nuxt istemcisi)
// eğer bunu alan sunucuysa, istemci bunu tarayıcıya iletmelidir
// sunucuyla kendi iletişimi için PHP
// burada bir istemci yönlendirmesi söz konusudur
// oturum çerezini alıyoruz PHP
const phpSessionCookie = context.store.state.phpSessionCookie
if (phpSessionCookie) {
// Varsa, PHP oturum çerezini tarayıcıya atanır
document.cookie = phpSessionCookie
}
...
}
Müşterinin yetkisiz rotalara gitmesini önlemek için, müşteri navigasyon menüsünde yalnızca yetkili rotaları sunacağız. [components/navigation] bileşeni şu şekilde olur:
<template>
<!-- Üç seçenekli Bootstrap menüsü -->
<b-nav vertical>
<b-nav-item v-if="$store.state.jsonSessionStarted && !$store.state.userAuthenticated" to="/authentification" exact exact-active-class="active">
Authentification
</b-nav-item>
<b-nav-item
v-if="$store.state.jsonSessionStarted && $store.state.userAuthenticated && !$store.state.adminData"
to="/get-admindata"
exact
exact-active-class="active"
>
Requête AdminData
</b-nav-item>
<b-nav-item v-if="$store.state.jsonSessionStarted && $store.state.userAuthenticated" to="/fin-session" exact exact-active-class="active">
Fin session impôt
</b-nav-item>
</b-nav>
</template>
- 4. satır: [Authentification] seçeneği, yalnızca jSON oturumu başlatılmış ancak kullanıcı henüz kimlik doğrulaması yapılmamışsa sunulur. jSON oturumu başlamamışsa veya kullanıcı zaten kimlik doğrulaması yapmışsa, bu seçenek sunulmaz;
- 7-11. satırlar: [Requête AdminData] seçeneği, yalnızca jSON oturumu başlatılmışsa, kullanıcı kimliği doğrulanmışsa ve [AdminData] verisi henüz alınmamışsa sunulur. Bu üç koşullardan herhangi biri karşılanmazsa (jSON oturumu başlatılmamışsa, kullanıcı kimliği doğrulanmamışsa veya [AdminData] verisi zaten alınmışsa), seçenek sunulmaz;
- 15. satır: [Fin session impôt] seçeneği, jSON oturumu başlatıldığında ve kullanıcı kimliği doğrulandığında sunulur, aksi takdirde sunulmaz;
16.3. [nuxt] sunucusunun yönlendirilmesi
Sunucu yönlendirmesi genellikle istemci yönlendirmesinden daha karmaşıktır, çünkü kullanıcı tarayıcısının adres çubuğuna herhangi bir URL yazabilir. Bunu olduğu gibi bırakabiliriz (sonuçta kullanıcının bunu yapması beklenmez) ya da durumu kontrol etmeye çalışabiliriz. Örnek olarak burada bunu yapacağız; çünkü [nuxt-12] uygulamasında, vergi hesaplama sunucusu bu tür elle girilen URL adreslerine karşı iyi korunmuş durumda ve uygun hata mesajlarını gönderebiliyor. Bunu, yönlendirme kontrolünün hiç olmadığı [next-12] örneğinde görmüştük.
Bir [nuxt] sunucusunun yönlendirmesi, yeniden yönlendirme kavramı açısından bir [nuxt] istemcisinden çok farklıdır:
- bir [nuxt] sunucusu yönlendirildiğinde, yönlendirme hedefini içeren bir yönlendirme komutu istemci tarayıcısına gönderir. Tarayıcı daha sonra [nuxt] sunucusuna, kendisine iletilen hedefi talep eden yeni bir istek gönderir. Her şey, sanki kullanıcı yönlendirme hedefinin adresini elle girmiş gibi gerçekleşir: tüm URL uygulaması yeniden başlatılır ve dolayısıyla tüm yaşam döngüsü (sunucu eklentileri, depo, sunucu yönlendirmesi, sayfalar) yeniden başlar;
- bir [nuxt] istemcisi yönlendirildiğinde ise böyle bir durum yaşanmaz. Sadece bir sayfa değişimi gerçekleşir; bu, kullanıcının yönlendirme hedefine giden bir bağlantıya tıklamış olsaydı elde edilecek sonuçla aynıdır. Bu durumda yaşam döngüsü farklıdır (istemci yönlendirmesi, yolun hedefinin görüntülenmesi);
Bu nedenle, her iki kod birbirine benzer görünse bile, istemci yönlendirmesini sunucu yönlendirmesinden ayırmak daha iyidir.
[middleware/server/routing] sunucu yönlendirme komut dosyası şu şekilde olacaktır:
/* eslint-disable no-console */
export default function(context) {
// Bu kodu kim çalıştırıyor?
console.log('[middleware server], process.server', process.server, ', process.client=', process.client)
// depolardan bazı bilgiler alınıyor [nuxt]
const store = context.store
// nereden geliyoruz?
const from = store.state.from || 'nowhere'
...
}
- istemci yönlendirmesinde, yönlendirme işlevi, geldiğimiz sayfanın yolu olan [context.from] özelliğine sahip [context] bağlamını alır. Gideceğimiz yol, [context.route] ile elde edilir;
- sunucu yönlendirmesinde, yönlendirme işlevi [context] bağlamını, [context.from] özelliği olmadan alır. Sunucu yönlendirmesi, yalnızca [nuxt] sunucusuna manuel olarak bir URL talebi gönderildiğinde devreye girer. Bu durumda [nuxt] uygulamasının tamamının sıfırlandığı bilinmektedir. Sanki sıfırdan başlıyormuşuz gibi olur ve bu nedenle ‘önceki sayfa’ kavramı ortadan kalkar;
- [nuxt] oturumu sayesinde, sunucunun bu oturumu geri alabileceği ve dolayısıyla sıfırdan başlamayacağı bilinmektedir. Dolayısıyla, bu [nuxt] oturumunda ve daha spesifik olarak bu oturumun depolama alanında, [nuxt] sunucusuna bir URL talebi gönderilmeden önce istemci tarayıcısı tarafından görüntülenen son sayfanın adını depolayacağız;
- 7-9. satırlar: İstemci tarayıcısı tarafından görüntülenen son sayfanın adını alıyoruz. Uygulamanın başlatılması sırasında, bu bilgi [from] depoda mevcut değildir. Bunun üzerine [nowhere] adı, [from] değişkenine atanır;
[nuxt] sunucusunun, istemci tarayıcısı tarafından görüntülenen son sayfanın adını depodan alabilmesi için, [nuxt] istemcisinin de bu bilgiyi depoya kaydetmesi gerekir. Dolayısıyla, [nuxt] istemcisinin yönlendirme komut dosyası şu şekilde tamamlanır:
/* eslint-disable no-console */
export default function(context) {
// Bu kodu kim çalıştırıyor?
console.log('[middleware client], process.server', process.server, ', process.client=', process.client)
// Tarayıcıdaki PHP oturum çerezinin yönetimi
// Tarayıcıdaki PHP oturum çerezi, nuxt oturumunda bulunanla aynı olmalıdır
// [fin-session] eylemi, yeni bir PHP çerezi alır (hem sunucu hem de Nuxt istemcisi)
// eğer bunu alan sunucuysa, istemci bunu tarayıcıya iletmelidir
// sunucuyla kendi iletişimi için PHP
// burada bir istemci yönlendirmesi söz konusudur
// oturum çerezini alıyoruz PHP
const phpSessionCookie = context.store.state.phpSessionCookie
if (phpSessionCookie) {
// varsa, PHP oturum çerezini tarayıcıya atanır
document.cookie = phpSessionCookie
}
// gideceğimiz sayfanın adını oturuma kaydediyoruz - sunucu yönlendirmesi yok
context.store.commit('replace', { serverRedirection: false, from: context.route.name })
// store'u [nuxt] oturumuna kaydedilir
const session = context.app.$session()
session.value.store = context.store.state
session.save(context)
}
- 19-24. satırlar eklenir;
- 20. satır: Görüntülenecek olan [context.route.name] sayfasının adı depoya eklenir; bu sayfa, bir sonraki yönlendirme sırasında "gelindiği sayfa" olacaktır. Ayrıca, [nuxt] sunucusundaki yönlendirmede, bu sunucunun mevcut yönlendirmenin [nuxt] sunucusundaki önceki bir yönlendirmeden kaynaklanıp kaynaklanmadığını bilmesi gerektiği görülecektir. Burada durum böyle değildir ve bu nedenle [serverRedirection] özelliğini [false] olarak ayarlıyoruz;
- 22-24. satırlar: depolama durumu [nuxt] oturumuna kaydedilir (satır 23), ardından [nuxt] oturumu bir çerezde saklanır (satır 24) ve bu çerez de [nuxt] istemcisinin tarayıcısında saklanacaktır;
[nuxt] sunucusunun yönlendirme komut dosyasına geri dönelim:
/* eslint-disable no-console */
export default function(context) {
// Bu kodu kim çalıştırıyor?
console.log('[middleware server], process.server', process.server, ', process.client=', process.client)
// depolamadan bazı bilgiler alınır [nuxt]
const store = context.store
// nereden geliyoruz?
const from = store.state.from || 'nowhere'
// Nereye gidiyoruz?
const to = context.route.name
// olası yönlendirme
let redirection = ''
// yönlendirme yönetimi tamamlandı
let done = false
// [nuxt] sunucusundan bir yönlendirmenin içinde miyiz?
if (store.state.serverRedirection) {
// yapılacak bir şey yok
done = true
}
// Bu bir sayfa yenileme mi?
if (to === from) {
// yapılacak bir şey yok
done = true
}
// [nuxt] sunucusunun gezinme kontrolü
// [navigation] bileşeninde istemci gezinmesinden esinleniliyor
// PHP oturumu başlatılmamışsa
if (!done && !store.state.jsonSessionStarted && to !== 'index') {
// yönlendirme
redirection = 'index'
// işlem tamamlandı
done = true
}
// kullanıcının kimliği doğrulanmamış olması durumu
if (!done && store.state.jsonSessionStarted && !store.state.userAuthenticated && to !== 'authentification') {
// yönlendirme
redirection = from
// işlem tamamlandı
done = true
}
// kullanıcının kimlik doğrulaması yapılmış olduğu durum
if (!done && store.state.jsonSessionStarted && store.state.userAuthenticated && to !== 'get-admindata' && to !== 'fin-session') {
// aynı sayfada kalınır
redirection = from
// işlem tamamlandı
done = true
}
// [adminData] elde edildiğinde
if (!done && store.state.jsonSessionStarted && store.state.userAuthenticated && store.state.adminData && to !== 'fin-session') {
// aynı sayfada kalınır
redirection = from
// iş tamamlandı
done = true
}
// tüm kontroller yapıldı ---------------------
// yönlendirme mi?
if (redirection) {
// yönlendirme mağazada not edildi
store.commit('replace', { serverRedirection: true })
} else {
// yönlendirme yok
store.commit('replace', { serverRedirection: false, from: to })
}
// depolama alanını oturuma kaydediyoruz [nuxt]
const session = context.app.$session()
session.value.store = store.state
session.save(context)
// gerekirse yönlendirme yapılıyor
if (redirection) {
context.redirect({ name: redirection })
}
}
- 6-9. satırlar: [nuxt] sunucusunun depolama alanında bulunan [from] değerini alıyoruz;
- 11. satır: mevcut yönlendirmenin hedefi kaydedilir;
- 13. satır: Yönlendirme, istemci tarayıcısının yeniden yönlendirilmesine neden olabilir. [redirection] bu yeniden yönlendirmenin hedefi olacaktır;
- 15. satır: [done]'ten [true]'e yönlendirme, yönlendirmenin tamamlandığını gösterir;
- satır 17-21: Öncelikle, mevcut yönlendirmenin istemci tarayıcısına gönderilen bir yönlendirme isteğinden kaynaklanıp kaynaklanmadığı kontrol edilir. Bu bilgi, deponun [serverRedirection] özelliğinde saklanır. Bu özellik "true" ise, bu durumda [nuxt] sunucusu, [nuxt] sunucusuna yapılan önceki istek sırasında istemci tarayıcısına bir yönlendirme göndermiştir. Bu durumda, yapılacak bir yönlendirme yoktur. Bir önceki istek sırasında, [nuxt] sunucusunun yönlendiricisi, istemci tarayıcısının yönlendirilmesi gerektiğine karar vermiştir. Bu karar, yeni bir yönlendirmeyle sorgulanmamalıdır;
- 23-27. satırlar: Mevcut yönlendirmenin bir sayfa yenilemesi olup olmadığına bakılır. Eğer öyleyse, işlem devam eder;
- 29. satırdan itibaren, [nuxt] istemcisinin [navigation] bileşeninde uygulanan kurallara geri dönülür (bkz. önceki paragraf);
- satır 32-38: jSON oturumu başlatılmamışsa ve yönlendirmenin hedefi [index] sayfası değilse bu durum işlenir. Bu durumda, istemci tarayıcısı [index] sayfasına yönlendirilir;
- satır 40-46: jSON oturumu başlamış, kullanıcı kimliği doğrulanmamış ve mevcut yönlendirme hedefi [authentification] sayfası değilse bu durum ele alınır. Bu durumda, yönlendirme reddedilir ve mevcut konumda kalınır;
- 48-54. satırlar: jSON oturumu başlatılmış, kullanıcı kimliği doğrulanmış ve mevcut yönlendirmenin hedefi, o anda tek olası hedefler olan [get-admindata] sayfası veya [fin-session] sayfası değilse bu durum işlenir. Bu durumda, istenen yönlendirme reddedilir ve önceki duruma geri dönülür;
- 56-62. satırlar: [adminData] elde edildiği durum ele alınır. Bu durumda, yönlendirme için tek bir hedef vardır: [fin-session] sayfası. İstenen bu sayfa değilse, yönlendirme reddedilir ve önceki duruma geri dönülür;
- 64-72. satırlar: Yönlendirme gerçekleştiyse, bunu [nuxt] sunucusunun depolama alanında şu şekilde kaydediyoruz: [serverRedirection: true]. Depolama alanındaki [from] özelliğine bir değer atanmadığını belirtelim. Bunun nedeni, istemci tarayıcısından bir yönlendirme olacağı ve bu durumda yönlendirme yapılmadığını (satır 17-20) ve deponun [from] özelliğinin kullanılmadığını görmüş olmamızdır;
- 66-69. satırlar: Yönlendirme yoksa, bu durum [nuxt] sunucusunun depolama alanında da [serverRedirection: false] olarak kaydedilir. Ayrıca, devam eden yönlendirme [to] sayfasını gösterecek ve bu sayfa, bir sonraki istek için (istemci veya [nuxt] sunucusu) önceki sayfa haline gelecektir. Bu nedenle [from: to] yazılır;
- 73-76. satırlar: store, bir çerezde saklanan [nuxt] oturumuna kaydedilir;
- 77-80. satırlar: [redirection] boş değilse, tarayıcıdan yeniden yönlendirilmesini istenir. Aksi takdirde (burada gösterilmemiştir), [nuxt] sunucusunun yaşam döngüsü devam edecektir: [to] sayfası, [nuxt] sunucusu tarafından işlenecek ve [nuxt] oturum çerezi ile birlikte [nuxt] istemci tarayıcısına gönderilecektir;
Burada [nuxt] sunucusu için seçilen yönlendirme keyfi bir seçimdir. Başka bir yönlendirme seçilebilirdi ya da daha önce de belirtildiği gibi hiç yönlendirme yapılmayabilirdi. Yukarıda seçilen yönlendirmenin avantajı, kullanıcı tarafından talep edilen URL ne olursa olsun, uygulamanın her zaman kararlı bir durumda kalmasını sağlamasıdır.
Sonunda yüklenen sayfa orijinal sayfa olduğunda bir noktayı iyileştirebiliriz. İki durum söz konusudur:
- kullanıcı sayfanın yeniden yüklenmesini tetiklemiştir (to===from);
- orijinal sayfaya yönlendirmeler vardır (redirection===from);
Her iki durumda da orijinal sayfa, vergi hesaplama sunucusuna yaptığı asenkron çağrı ile yeniden çalıştırılacaktır. Bir örnek verelim. Kullanıcı, kimlik doğrulaması yapıldıktan sonra sayfayı (F5) yeniden yükler. Bu durumda, yukarıdaki yönlendirme şemasında şunu görürüz: [to]=[from]=[authentification]. Yönlendirme yoktur. [to=authentification] sayfası, [nuxt] sunucusu tarafından çalıştırılacaktır. Herhangi bir işlem yapılmazsa, [asyncData] işlevi yeniden çalıştırılacaktır. Kimlik doğrulama işlemi zaten gerçekleştirildiği için bu gereksizdir.
[authentification] sayfasını biraz değiştirerek durumu iyileştirebiliriz:
// asenkron veriler
async asyncData(context) {
// günlük
console.log('[authentification asyncData started]')
// sayfa daha önce istenmişse işlemler iki kez yapılmaz
if (process.server && context.store.state.userAuthenticated) {
console.log('[authentification asyncData canceled]')
return { result: '[succès]' }
}
// istemci [nuxt]
if (process.client) {
// bekleme başlangıcı
context.app.$eventBus().$emit('loading', true)
// hata yok
context.app.$eventBus().$emit('errorLoading', false)
}
try {
// sunucuya kimlik doğrulaması yapılıyor
...
- 6-9. satırlar: Sayfa [nuxt] sunucusu tarafından çalıştırılıyorsa ve depoda kimlik doğrulamasının zaten yapıldığı tespit edilirse, istenen sonuç doğrudan döndürülür (8. satır);
Aynı işlem tüm sayfalar için yapılır:
[index] sayfası:
// asenkron veriler
async asyncData(context) {
// günlük
console.log('[index asyncData started]')
// sayfa daha önce istenmişse işlem tekrarlanmaz
if (process.server && context.store.state.jsonSessionStarted) {
console.log('[index asyncData canceled]')
return { result: '[succès]' }
}
try {
...
[get-admindata] sayfası
// asenkron veriler
async asyncData(context) {
// günlük
console.log('[get-admindata asyncData started]')
// sayfa daha önce istenmişse işlem iki kez yapılmaz
if (process.server && context.store.state.adminData) {
console.log('[get-admindata asyncData canceled]')
return { result: context.store.state.adminData }
}
// istemci
if (process.client) {
// bekleme başlangıcı
context.app.$eventBus().$emit('loading', true)
// hata yok
context.app.$eventBus().$emit('errorLoading', false)
}
try {
...
[fin-session] sayfası
// asenkron veriler
async asyncData(context) {
// günlük
console.log('[fin-session asyncData started]')
// sayfa daha önce istenmişse işlem iki kez yapılmaz
if (process.server && context.store.state.jsonSessionStarted && !context.store.state.userAuthenticated) {
console.log('[fin-session asyncData canceled]')
return { result: "[succès]. La session jSON reste initialisée mais vous n'êtes plus authentifié(e)." }
}
// müşteri durumu [nuxt]
if (process.client) {
// bekleme başlangıcı
context.app.$eventBus().$emit('loading', true)
// hata yok
context.app.$eventBus().$emit('errorLoading', false)
}
try {
16.4. Exécution
Bu örneği çalıştırmak için, temiz bir durumdan başlamak amacıyla, çalıştırma öncesinde [nuxt] istemcisini çalıştıran tarayıcıdan [nuxt] oturum çerezini ve PHP çerezini silmeye dikkat etmelisiniz. Aşağıda Chrome tarayıcısıyla bir örnek verilmiştir:

16.5. Conclusion
[nuxt] sunucusunun yönlendirilmesi karmaşıktır, çünkü kullanıcının elle girebileceği tüm URL değerlerini öngörmek gerekir. Bu, tipik bir örnektir. Bir [nuxt] uygulaması bu şekilde kullanılmak üzere tasarlanmamıştır. [index] sayfası, [nuxt] sunucusunun yönlendiricisi tarafından sunulduktan sonra, sunucuya yapılan sonraki çağrılar bir hata sayfasına yönlendirilebilir.
[nuxt-13] örneğimizde, [nuxt] sunucusunun yönlendirmesi gereksizdi. [nuxt-12] örneğindeki varsayılan yönlendirme (aslında yönlendirme yok) gayet uygun düşüyordu.