Skip to content

8. [nuxt-05] örneği: oturum çerezi ile depolama alanının kalıcılığı

Amaç: [Vuex] depolama alanının sunucuya yapılan her istek sırasında sıfırlanmamasını istiyoruz. Bunu sağlamak için bir oturum çerezi kullanacağız:

  • depolama alanı sunucu tarafından başlatılacak ve sunucu tarafından bir oturum çerezine yerleştirilecektir;
  • istemci tarayıcısı bu oturum çerezini alacak ve sunucuya yapılan her yeni istekle birlikte otomatik olarak gönderecektir;
  • sunucu bu oturum çerezini alabilecek ve içinde bulunan, istemci tarafından güncellenmiş depo ile çalışabilecektir;

8.1. Présentation

[nuxt-05] projesi, başlangıçta [nuxt-04] projesinin kopyalanmasıyla elde edilir:

Image

Göreceğiz ki sadece [store / index.js] dosyası değişecektir.

[nuxt] ile çerezleri kullanmak için, [yarn] ile birlikte bir VSCode terminaline kurduğumuz [cookie-universal-nuxt] modülünü kullanacağız:

Image

  • [4]'te [yarn add cookie-universal-nuxt] komutunu giriyoruz;

Böylece, [dvp] projesinin [package.json] dosyasına yeni bir modül eklenir:


...
},
  "dependencies": {
    "@nuxtjs/axios": "^5.3.6",
    "bootstrap": "^4.1.3",
    "bootstrap-vue": "^2.0.0",
    "cookie-universal-nuxt": "^2.0.19",
    "nuxt": "^2.0.0"
},

8.2. [nuxt.config.js] yapılandırma dosyası

[nuxt]'in [cookie-universal-nuxt]'in çerezlerini kullanabilmesi için, bu modülün [nuxt.config.js] yapılandırma dosyasında tanımlanması gerekir:


...
],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Belge: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Belge: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    // https://www.npmjs.com/package/cookie-universal-nuxt
    'cookie-universal-nuxt'
  ],
...

  • 12. satırda, [cookie-universal-nuxt] modülü, [nuxt]'in [6] modül tablosuna eklenir;

[nuxt.config.js] dosyası sonuç olarak şu şekildedir:


export default {
  mode: 'universal',
  /*
   ** Headers of the page
   */
  head: {
    title: 'Introduction à [nuxt.js]',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      {
        hid: 'description',
        name: 'description',
        content: 'ssr routing loading asyncdata middleware plugins store'
      }
    ],
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: '#fff' },
  /*
   ** Global CSS
   */
  css: [],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    // Belge: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    // Belge: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Belge: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    // https://www.npmjs.com/package/cookie-universal-nuxt
    'cookie-universal-nuxt'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  },
  // kaynak kod dizini
  srcDir: 'nuxt-05',
  // yönlendirici
  router: {
    // uygulamanın URL kökü
    base: '/nuxt-05/'
  },
  // sunucu
  server: {
    // hizmet bağlantı noktası, varsayılan olarak 3000
    port: 81,
    // dinlenen ağ adresleri, varsayılan olarak localhost: 127.0.0.1
    // 0.0.0.0 = makinedeki tüm ağ adresleri
    host: 'localhost'
  },
  // ortam
  env: {
    maxAge: 60 * 5
  }
}
  • 79. satır: Dosyaya [env] anahtarı eklenmiştir. Bu anahtar, ayrılmış bir kelimedir. Bu nesnede bildirilen öğeler, uygulama öğeleri içindeki [context.env] nesnesinden erişilebilir;
  • 80. satır: [maxAge] özniteliği, oturum çerezinin maksimum ömrünü belirtir; bu süre, çerezin en son başlatıldığı andan itibaren ölçülür. Bu süre saniye cinsinden ifade edilir. Burada 5 dakikalık bir ömür ayarlanmıştır;

8.3. Depolamanın kalıcılığı ilkesi

İstemci ile sunucu arasında alışverişi yapılan çerezler, her iki tarafta (istemci ve sunucu) şu konumda bulunur:

  • [context.app.$cookies], [context] nesnesinin mevcut olduğu her yerde, yani hemen hemen her yerde;
  • [this.$cookies] bir görünümün içinde;

[...$cookies.get(‘nom_du_cookie’)] ifadesiyle belirli bir çereze ulaşılır. [...$cookies.set(‘nom_du_cookie’, valeur_du_cookie)] ifadesiyle bir çerezin değeri belirlenir.

Mağazanın kalıcı çerezinin çalışma prensibi şu şekildedir:

  • sunucu, [nuxtServerInit] işlevinde depoyu başlatırken, deponun durumu ‘session’ adlı bir çerezde saklanacaktır;
  • "session" adlı çerez, sunucunun HTTP yanıtının bir parçası olacaktır. Bir tarayıcının, sunucunun kendisine gönderdiği çerezleri sunucuya geri gönderdiği bilinmektedir. Tarayıcı, sunucuya yaptığı her yeni istekte bunu yapar. Ayrıca, sunucunun müşteriye gönderdiği sayfanın içinde depoyu da gönderdiği bilinmektedir;
  • tarayıcı içinde, istemci uygulaması sunucu tarafından gönderilen veriyi alır ve ardından işini yapar. Uygulamanın veriyi her değiştirdiğinde, verinin yeni durumunun tarayıcı tarafından kaydedilen ‘session’ çerezine depolanmasını sağlayacağız;
  • kullanıcı sunucuya bir çağrı yaparsa, istemci tarayıcısı sunucunun daha önce kendisine gönderdiği tüm çerezleri, özellikle de ‘session’ adlı çerezi otomatik olarak geri gönderecektir;
  • bu çağrının ardından sunucu depoyu yeniden sıfırladığında, ‘session’ adlı çerezi alır ve deponun durumunu bu çerezin değeriyle başlatır;
  • böylece istemci ile sunucu arasında deponun sürekliliği sağlanır;

8.4. Deponun Başlatılması

Depo, [store / index.js] dosyasında uygulanmıştır:


/* eslint-disable no-console */
export const state = () => ({
  // sayaç
  counter: 0
})

export const mutations = {
  // sayaç değerini bir artırma [inc]
  increment(state, inc) {
    state.counter += inc
  },
  // durumun değiştirilmesi
  replace(state, newState) {
    for (const attr in newState) {
      state[attr] = newState[attr]
    }
  }
}

export const actions = {
  async nuxtServerInit(store, context) {
    // bu kodu kim çalıştırıyor?
    console.log('nuxtServerInit, client=', process.client, 'serveur=', process.server, 'env=', context.env)
    // bir sözün tamamlanmasını bekliyoruz
    await new Promise(function(resolve, reject) {
      // burada normalde asenkron bir işlev vardır
      // bir saniye bekleyerek bunu simüle ediyoruz
      setTimeout(() => {
        // oturumu başlat
        initStore(store, context)
        // başarılı
        resolve()
      }, 1000)
    })
  }
}

function initStore(store, context) {
  // Cari istekte oturum çerezi var mı?
  const cookies = context.app.$cookies
  const session = cookies.get('session')
  if (!session) {
    // mevcut oturum yok
    console.log("nuxtServerInit, initialisation d'une nouvelle session")
    // depolama alanı başlatılıyor
    store.commit('increment', 77)
  } else {
    console.log("nuxtServerInit, reprise d'une session existante")
    // depolama alanı oturum çerezi ile güncelleniyor
    store.commit('replace', session.store)
  }
  // depolama alanı oturum çerezine ekleniyor
  cookies.set('session', { store: store.state }, { path: context.base, maxAge: context.env.maxAge })
  // günlük
  console.log('initStore terminé, store=', store.state)
}

Açıklamalar

  • 2-5. satırlar: depo, bir sayaçtan oluşacaktır;
  • 9-11. satırlar: Bu sayaç artırılabilir;
  • 13-17. satırlar: deponun durumu yeni bir durumdan başlatılabilir. Bu işlev, deponun burada olduğu gibi yalnızca sayıcıyla sınırlı olmadığı durumlarda olası bir başlatma işlemini göstermek için eklenmiştir;
  • satır 21-35: [nuxtServerInit] fonksiyonu değişmemiştir;
  • satır 30: Bir saniyelik bekleme süresi dolduğunda, satır 38-56'daki işlev kullanılarak depo sıfırlanır;
  • 40-41. satırlar: Öncelikle ‘session’ adlı çerezi alınır:
    1. uygulamanın ilk çalıştırılmasında ve sunucuya yapılan ilk istekte bu çerez henüz mevcut olmayacaktır. Bu durumda çerez oluşturulur (satır 53) ve istemci tarayıcısına gönderilir;
    2. uygulamanın aynı çalıştırılmasında ve sunucuya yapılan 2., 3., ... numaralı isteklerde bu çerez mevcut olacaktır, çünkü istemci tarayıcısı sunucuya yapılan her yeni istekle birlikte onu geri gönderecektir;
    3. uygulamanın ikinci kez çalıştırılması sırasında ve sunucuya yapılan ilk istekte bu çerez de mevcut olabilir. Nitekim, 1. adımın sonunda çerez, belirli bir geçerlilik süresi ile tarayıcıda depolanmıştır. Bu geçerlilik süresi aşılmamışsa, ‘session’ adlı çerez sunucuya yapılan ilk istekle birlikte gönderilecektir

Özetle, sunucuya yapılan her istek için: ‘session’ adlı çerez istemci tarayıcısında zaten depolanmışsa sunucu bunu alacaktır, aksi takdirde almayacaktır.

  • 42-47. satırlar: Sunucu oturum çerezini almazsa, 46. satırla depo başlatılır;
    • ardından 53. satırda, ‘session’ adlı bir çerez oluşturulur ve sunucunun HTTP yanıtına eklenir. Çerezin değeri, [{ store: store.state }] nesnesidir. Dolayısıyla, oturum çerezine deponun kendisi değil, deponun durumu eklenir;
    • [set] işlevinin üçüncü parametresi bir seçenek nesnesidir:
      • [path], bu çerezin hangi URL'e geri gönderilmesi gerektiğini belirtir. [context.base], [nuxt-05] uygulamasının temel URL'sidir. Bu, [nuxt.config.js] dosyasında tanımlanmıştır:

  // yönlendirici
  router: {
    // uygulamanın URL kökü
    base: '/nuxt-05/'
},
      • [maxAge], tarayıcıdaki çerezin saniye cinsinden ömrüdür. Bu süre geçtikten sonra tarayıcı, çerezi sunucuya geri göndermez. [context.env.maxAge] ise yine [nuxt.config.js] dosyasında kayıtlı bir değeri döndürür:
1
2
3
4
// ortam
  env: {
    maxAge: 60 * 5
}

[env], yapılandırma dosyasındaki ayrılmış bir anahtar kelimedir. Burada geçerlilik süresi 5 dakikaya ayarlanır. Bu süre, tarayıcının oturum çerezini en son aldığı zamandan itibaren hesaplanır. Bu süre geçtikten sonra çerez sunucuya geri gönderilmez ve sunucu yeni bir oturum başlatmak zorunda kalır;

  • 48-50. satırlar: Sunucu oturum çerezini alırsa, deponun durumu oturum çerezindeki [store] nesnesiyle başlatılır. Bu nesnenin, deponun kaydedilmiş durumunu içerdiğini hatırlayalım;
    • ardından 53. satırda, oturum çerezi istemci tarayıcısına gönderilen yanıtta yer alır:
      • [get] işlevi, sunucu tarafından alınan istekte oturum çerezini arar;
      • [set] işlevi, oturum çerezini sunucunun istemci tarayıcısına gönderdiği yanıtta yer alır;

8.5. Mağaza sayacının artırılması

[index.vue] sayfasındaki sayacın artırılması şu şekilde gerçekleşir:


  // olay yönetimi
  methods: {
    incrementCounter() {
      console.log('incrementCounter')
       // sayaçta 1 artış
      this.$store.commit('increment', 1)
       // görüntülenen değerin değiştirilmesi
      this.value = this.$store.state.counter
       // depolanan verinin oturum çerezine kaydedilmesi
      this.$cookies.set('session', { store: this.$store.state }, { path: this.$nuxt.context.base, maxAge: this.$nuxt.context.env.maxAge })
    }
}

İstemci tarafında, depo her değiştirildiğinde, bunun oturum çerezine kaydedilmesi gerekir. Zira kullanıcı istediği zaman manuel olarak bir URL isteğinde bulunabilir ve bu durumda sunucuya güncel bir depo gönderilebilmesi gerekir. Bu nedenle, 10. satırda, depo sayacını artırdıktan sonra, deponun durumunu oturum çerezine kaydediyoruz:

  • çerezler [this.$cookies] özelliğinde bulunur;
  • [this.$store.state] depolama alanının durumu, [store] anahtarıyla ilişkili çerezde kaydedilir;
  • çerezin yolu [context.base]'tir. Bir görünümde, bağlam [this.$nuxt.context]'te bulunur;
  • çerezin ömrü [context.env.maxAge] olup, burada [this.$nuxt.context.env.maxAge] özelliğinde bulunur;

8.6. [nuxt-05] örneğinin çalıştırılması

[nuxt-05] uygulamasını başlatıyoruz:

Image

Aşağıdaki ekran görüntüleri Chrome tarayıcısından alınmıştır. URL [http://localhost:81/nuxt-05/] adresini giriyoruz. /nuxt-05'in sonundaki / işaretini eklemeyi unutmayın, aksi takdirde beklenen sonuçları alamazsınız:

Image

  • [4]'te, store'un başlangıç değerini (77) elde ettik;

Tarayıcı günlüklerini inceleyelim (F12):

Image

  • [5-6]'te, sunucu günlükleri;
  • [7]'te, sunucunun yeni bir oturum başlattığını görüyoruz. Bu, sunucunun oturum çerezi almadığı anlamına gelir;
  • [8]'te, sayaç 77 değeriyle başlatılıyor;
  • [9]'te, sunucudaki (9) ve istemcideki (10) [index] sayfaları sayacın aynı değerini doğru bir şekilde gösteriyor;

Şimdi tarayıcı tarafından alınan çerezlere bakalım:

Image

  • [1]'te, [Application] sekmesini ve ardından [Cookies] [2] seçeneğini seçin. Tarayıcınızdaki tüm çerezler arasından, [http://localhost:81] etki alanına ait olanı seçin;
  • [4]'te, "session" adlı çerezi seçin. Eğer bu çerez yoksa, sayfayı yeniden yükleyin: belki de 5 dakikalık geçerlilik süresi dolmuştur;
  • [5]'te çerezin değeri. { : karakterlerinin kodlanması nedeniyle çok okunaklı olmasa da, sayacın 77 değerini ayırt edebiliriz;
  • [6]'te, çerezin URL değeri: bu URL her talep edildiğinde, tarayıcı çerezi sunucuya gönderecektir;
  • [7], çerezin geçerlilik süresinin sona erme saatidir. Bu saat aşıldığında, çerez tarayıcıda silinecektir;

Bu çerezin mevcut olduğundan emin olun. Eğer yoksa, sayfayı yeniden yükleyin (F5). Çerezi içeren sayfayı gördüğünüzde, sayfayı tekrar yeniden yükleyin (F5). Günlük kayıtları şu şekilde olur:

Image

Bu sefer [3]'te, sunucu oturum çerezini başarıyla aldı. Bunu sunucuya gönderen, istemci tarayıcısıdır.

Şimdi, sayacı artırın ve ara sıra mevcut sayfayı yeniden yükleyin (F5); ister [index] ister [page1] olsun, sayaçın, [nuxt-04] örneğindeki gibi 77’ye dönmediğini, ancak sayfanın yeniden yüklenmesinden önce istemci tarayıcısında sahip olduğu değeri koruduğunu göreceksiniz:

Image

Image

Tarayıcı günlükleri şu şekildedir:

Image

Not: Testler için, sunucuya yapılacak bir sonraki istek sırasında sunucu tarafından başlatılan yeni bir oturumla başlamak üzere, tarayıcıda depolanan [5] oturum çerezini silmeniz gerekebilir.

Son olarak, [incrementCounter] sayfasındaki [index] işlevinin, istemci tarayıcısında depolanan oturum çerezine etkisini gösterelim:


// olay yönetimi
  methods: {
    incrementCounter() {
      console.log('incrementCounter')
      // sayaç 1 artırıldı
      this.$store.commit('increment', 1)
      // görüntülenen değerin değiştirilmesi
      this.value = this.$store.state.counter
      // değişken değerinin oturum çerezine kaydedilmesi
      this.$cookies.set('session', { store: this.$store.state }, { path: this.$nuxt.context.base, maxAge: this.$nuxt.context.env.maxAge })
    }
  }
  • 10. satır: Sayaçtaki değişiklik oturum çerezine yansıtılır;

Bu noktayı doğrulayalım. Şu durumdan yola çıkıyoruz:

Image

  • [4]'te, oturum çerezindeki sayaç, görüntülenen [1] değerini doğru bir şekilde yansıtıyor;

Şimdi sayacı bir artıralım: [5]. [4] şeklindeki oturum çerezi şu şekilde değişir:

Image

  • [7]'e dönüşür; oturum çerezinin sayacı 84'e geçmiştir. Bunu görmek için [8] görünümünü yenilemeniz gerekir. Bunun için [Storage] veya [9] seçeneklerinden birini seçin, ardından [8] seçeneğini yeniden seçin. O zaman oturum çerezinin yeni değeri görünmelidir;