Да приемем този сценарий: създали сте приложение Next.js с помощта на новия рутер за приложения и трябва да съхранявате чувствителни данни за потребителска сесия като токен за достъп, токен за опресняване или може би просто данни от формуляри, до които искате да имате достъп в уеб приложението.

Можете да използвате вградената динамична функция cookies(), за да съхранявате тези данни в клиентски бисквитки, но проблемът с използването на бисквитки е, че те се съхраняват от страна на клиента и са изложени и уязвими на Cross Site Scripting (XSS) , така че за чувствителни данни като токени за достъп това не е идеално.

Решение

За да разрешите този проблем, можете да използвате сесии от страна на сървъра, за да съхранявате данните си сигурно. Можете или да използвате временен кеш на паметта, или услуга за структура за съхранение на данни като Redis, PostgreSQL, dynamodb…. или други.

С наследения Page рутер това беше постижимо чрез използване на пакети като next-session, iron-session или express-session, но към момента, в който пиша това ръководство, App рутерът все още не се поддържа от тях.

Затова написах пакета next-app-session, който работи с манипулаторите на маршрута на App рутера, сървърните компоненти и сървърните действия. освен това той също така поддържа Page рутера и междинния софтуер.
https://www.npmjs.com/package/next-app-session

Как работи

Преди да разберем как да използваме пакета, може би си струва да опишем как работи:

  1. За нови потребители/посетители се генерира уникален идентификатор на потребителска сесия. (SID)
  2. Този SID ще бъде съхранен в бисквитка на клиентски браузър.
  3. Когато се съхраняват данни за потребител, неговата стойност на SID се използва като ключ за съхраняване на тези данни в хранилището на данни на сървъра и тези данни ще бъдат свързани само с този SID.
  4. Всяка заявка за четене на данни от сесията първо ще извлече SID от потребителските бисквитки и след това ще вземе свързаните данни от хранилището на данни.

Внедряване

В това ръководство ще използваме Redis като наше хранилище за данни. Ако желаете да използвате други магазини, този пакет трябва да работи с всеки „пакет за съхраняване на експресна сесия“, стига да е прекаран през функцията за помощна програма promisifyStore.

Така че нека първо да настроим нашия екземпляр на Redis store с помощта на докер, ако вече имате инстанция на Redis, можете да пропуснете тези стъпки

Настройте екземпляр на Redis store

  1. Актуализирайте/създайте файла docker-compose.yml, за да имате услугата Redis (уверете се, че използвате неизползван локален порт)
version: '3.8'
services:
 redis:
   image: redis:latest
   ports:
   - '6379:6379'

2. Стартирайте докер контейнера, в терминала отидете до вашия проект и стартирайте: docker-compose up

Настройване на пакет за следваща сесия на приложението

  1. Първо трябва да инсталирате пакета заедно с redis тези.
    npm i next-app-session ioredis connect-redis
  2. Създайте файл за инициализация, за този пример ще създадем този файл lib/session.ts и ще добавим следния код:
import nextAppSession, {promisifyStore} from 'next-app-session';
import Redis from 'ioredis';
import RedisStoreFactory from 'connect-redis';

// Your session data type
type MySessionData = {
  access_token?: string;
  refresh_token?: string;
  counter?: number;
}

export const session = nextAppSession<MySessionData>({
  name: 'EXAMPLE_SID', // The cookie name that will hold sid
  secret: 'secret goes here' , // Providing a secret will sign the SID before storing it in the cookie, providing extra security
  // Assign Redis store with connection details
  store: promisifyStore(
    new RedisStore({
      client: new Redis({
        // The redis instance connection details
        host: 'localhost',
        port: 6379
      }),
      prefix: 'exampleapp:' // having a prefix is optional but can be usefull if redis service is used by multiple applications
    })
  )
}); 

Използване

Сега, след като сте настроили пакетите, можете да започнете да използвате функцията session().

Важно: Вече можете да използвате session() само за Четене на данни от сесията в Сървърни компоненти или Четене+Записданни в Манипулатори на маршрути и „Действия на сървъра“. Той следва същите правила за използване като «динамичната функция cookies().

Пример за обработка на маршрут:

// Example for route handler
import { session } from '../lib/session'; //We import it from the initialisation file we created earlier

// Increment counter
export async function POST(request: Request) {
  // Read counter value froms session
  const current = await session().get('counter');

  //Increment value or assign 1 if no value exists
  const newValue = current ? Number(current) + 1 : 1;

  // Update counter session
  await session().set('counter', newValue);
}

Повече информация за това как да конфигурирате и използвате пакета можете да намерите в project README.file