Computer >> Máy Tính >  >> Lập trình >> Redis

Sử dụng Upstash Redis làm cửa hàng phiên cho Remix

Như khuôn khổ web đầy đủ, Remix cung cấp các API để đối phó với các trường hợp sử dụng máy chủ web phổ biến. Bài đăng này sẽ tập trung vào các phiên và lý do cũng như cách bạn có thể sử dụng Upstash để lưu trữ chúng.

Phiên là gì?

Tài liệu The Remix có phần giới thiệu rất hay về các phiên https://remix.run/docs/en/v1/api/remix#sessions

Nói cách khác - phiên là một cơ chế cho phép máy chủ và máy khách chia sẻ dữ liệu / trạng thái của người dùng. Ví dụ về việc sử dụng phiên là theo dõi trạng thái xác thực của người dùng, trạng thái giỏ hàng, tin nhắn flash, v.v.

Tại sao sử dụng Upstash Redis?

Dữ liệu phiên được lưu trữ trên máy chủ. Khi triển khai cơ sở hạ tầng không máy chủ hoặc một số cơ sở hạ tầng PASS (ví dụ:Heroku), bạn không thể duy trì dữ liệu trên hệ thống tệp của máy chủ vì nó có thể thay đổi theo mọi yêu cầu (không máy chủ) hoặc triển khai (PASS). Để duy trì dữ liệu, bạn nên lưu trữ dữ liệu người dùng trên cơ sở dữ liệu bên ngoài. Upstash Redis DB là một giải pháp tuyệt vời để lưu trữ dữ liệu phiên vì những lý do sau:

  • Tương tự như Redis Sessions, về bản chất, có key:value cấu trúc dữ liệu trong đó khóa là id của phiên và giá trị là dữ liệu được tuần tự hóa của nó.
  • Redis có cơ chế hết hạn được tích hợp sẵn để giảm nhu cầu dọn dẹp các phiên đã hết hạn.
  • Phiên có thể chứa dữ liệu người dùng nhạy cảm và Upstash Redis mã hóa tất cả dữ liệu được lưu trữ của nó.
  • Upstash đang sử dụng API REST HTTP đơn giản. HTTP là cách dễ nhất để giao tiếp từ cơ sở hạ tầng không máy chủ.

Cách sử dụng Upstash làm nhà cung cấp phiên trong Redis

Bài đăng này dựa trên Ví dụ về Lưu trữ Phiên Redis Sử dụng Upstash mà tôi đã viết. Hãy sao chép repo Remix và thử.

Bước 1 - Nhận khóa API Upstash của bạn

  • Truy cập https://upstash.com/ và tạo tài khoản mới
  • Tạo một Redis DB mới
  • Sao chép UPSTASH_REDIS_REST_URL &UPSTASH_REDIS_REST_TOKEN và lưu trữ chúng trong một tệp có tên .env trong phần gốc của dự án Remix của bạn.
  • Cài đặt dotenv - $ npm install --save-dev dotenv - Điều này sẽ cho phép bạn chèn các biến môi trường của mình từ .env tệp bạn vừa tạo.
  • Chuyển đến bạn package.json và thay thế dev dạng tập lệnh remix dev thành dotenv/config node_modules/.bin/remix dev .

Bước 2 - Triển khai createSessionStorage cốt lõi để tạo triển khai phiên Upstash

Remix cung cấp một API tuyệt vời để xây dựng tích hợp Phiên của riêng bạn bằng cách sử dụng createSessionStorage . Cho phép triển khai chức năng này để tích hợp Upstash.

// sessions/upstash.server.ts

import * as crypto from "crypto";

import { createSessionStorage } from "remix";

const upstashRedisRestUrl = process.env.UPSTASH_REDIS_REST_URL;

const headers = {
  Authorization: `Bearer ${process.env.UPSTASH_REDIS_REST_TOKEN}`,
  Accept: "application/json",
  "Content-Type": "application/json",
};

const expiresToSeconds = (expires) => {
  const now = new Date();
  const expiresDate = new Date(expires);
  const secondsDelta = expiresDate.getSeconds() - now.getSeconds();
  return secondsDelta < 0 ? 0 : secondsDelta;
};

// For more info check https://remix.run/docs/en/v1/api/remix#createsessionstorage
export function createUpstashSessionStorage({ cookie }: any) {
  return createSessionStorage({
    cookie,
    async createData(data, expires) {
      // Create a random id - taken from the core `createFileSessionStorage` Remix function.
      const randomBytes = crypto.randomBytes(8);
      const id = Buffer.from(randomBytes).toString("hex");
      // Call Upstash Redis HTTP API. Set expiration according to the cookie `expired property.
      // Note the use of the `expiresToSeconds` that converts date to seconds.
      await fetch(
        `${upstashRedisRestUrl}/set/${id}?EX=${expiresToSeconds(expires)}`,
        {
          method: "post",
          body: JSON.stringify({ data }),
          headers,
        }
      );
      return id;
    },
    async readData(id) {
      const response = await fetch(`${upstashRedisRestUrl}/get/${id}`, {
        headers,
      });
      try {
        const { result } = await response.json();
        return JSON.parse(result).data;
      } catch (error) {
        return null;
      }
    },
    async updateData(id, data, expires) {
      await fetch(
        `${upstashRedisRestUrl}/set/${id}?EX=${expiresToSeconds(expires)}`,
        {
          method: "post",
          body: JSON.stringify({ data }),
          headers,
        }
      );
    },
    async deleteData(id) {
      await fetch(`${upstashRedisRestUrl}/del/${id}`, {
        method: "post",
        headers,
      });
    },
  });
}

Hãy giải thích những gì chúng tôi vừa viết:Chúng tôi đã tạo một tệp có tên sessions/upstash.server.ts . Tệp này xuất một hàm có tên createUpstashSessionStorage . Hàm này nhận dưới dạng một tham số là cookie (sẽ nói thêm về điều đó sau) và sử dụng Remix createSessionStorage cốt lõi chức năng của nhà máy để triển khai trình cung cấp phiên mới.

Bên trong hàm, chúng tôi đã triển khai createSessionStorage giao thức để tạo một phiên mới (createData ), đọc giá trị phiên (readData ), cập nhật giá trị phiên (updateData ) và xóa phiên (deleteData ).

Mỗi chức năng sử dụng REST Upstash API để tương tác với Cơ sở dữ liệu Redis.

Những điều cần lưu ý:

  • Cookie được thông qua giữ cookie expiration date trong một js Date định dạng. Chúng tôi sử dụng expiresToSeconds chức năng chuyển đổi dữ liệu thành giây vì đây là những gì Redis mong đợi.
  • Khi đặt cookie, đừng quên đặt ngày hết hạn của nó. Redis sẽ tự động xóa các phiên đó khi chúng hết hạn.
  • Chúng tôi sử dụng crypto để tạo một id phiên duy nhất. Bạn có thể sử dụng các lựa chọn thay thế khác để tạo id duy nhất. Tôi đã chọn tùy chọn này vì nó giống như tùy chọn đang được sử dụng trong createFileSessionStorage lõi chức năng.

Bước 3 - sử dụng createSessionStorage trên ứng dụng của bạn

Bây giờ chúng tôi đã tạo triển khai lưu trữ phiên của riêng mình, hãy trình bày cách sử dụng nó.

Lưu ý rằng từ bây giờ không có gì cụ thể cho Upstash. Tất cả logic được gói gọn trong sessions/upstash.server.ts tệp.

// sessions.server.ts

import { createCookie } from "remix";
import { createUpstashSessionStorage } from "~/sessions/upstash.server";

// This will set the length of the session.
// For the example we use a very short duration to easily demonstrate its functionally.
const EXPIRATION_DURATION_IN_SECONDS = 10;

const expires = new Date();
expires.setSeconds(expires.getSeconds() + EXPIRATION_DURATION_IN_SECONDS);

const sessionCookie = createCookie("__session", {
  secrets: ["r3m1xr0ck1"],
  sameSite: true,
  expires,
});

const { getSession, commitSession, destroySession } =
  createUpstashSessionStorage({ cookie: sessionCookie });

export { getSession, commitSession, destroySession };

Tạo một tệp có tên sessions.server.ts và dán đoạn mã ở trên. Tệp này xuất ra 3 hàm getSession , commitSessiondestroySession . Các chức năng đó cho phép ứng dụng tương tác với phiên. Chúng tôi cũng tạo một cookie để lưu trữ tham chiếu đến phiên trong ứng dụng khách.

Thiết lập thời hạn hết hạn theo nhu cầu kinh doanh của bạn. Để biết thêm thông tin, hãy đọc https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

Sử dụng phiên trong các tuyến Phối lại

Sử dụng Phối lại, bạn có thể xác định mức sử dụng phiên trên mỗi tuyến đường. Trong ví dụ sau, chúng tôi sử dụng session trên routes/index.tsx . Ví dụ này chỉ trình bày cách sử dụng API phiên. Kết nối phiên với một logic nghiệp vụ cụ thể nằm ngoài phạm vi của bài đăng này.

Nếu bạn đang tìm kiếm ví dụ về cách sử dụng phiên để xác thực, hãy xem https://github.com/remix-run/remix/tree/main/examples/remix-auth-form

// routes/index.tsx

import type { LoaderFunction } from "remix";
import { json, useLoaderData } from "remix";
import { commitSession, getSession } from "~/sessions.server";

export const loader: LoaderFunction = async ({ request }) => {
  // Get the session from the cookie
  const session = await getSession(request.headers.get("Cookie"));
  const myStoredData = session.get("myStoredData");
  // If no session found (was never created or was expired) create a new session.
  if (!myStoredData) {
    session.set("myStoredData", "Some data");
    return json(
      {
        message: "Created new session",
      },
      {
        headers: {
          "Set-Cookie": await commitSession(session),
        },
      }
    );
  }
  // If session was found, present the session info.
  return json({
    message: `Showing Session info: ${myStoredData}`,
  });
};

export default function () {
  const data = useLoaderData();
  return <div>{data.message}</div>;
}

Ví dụ minh họa cách xử lý hai trạng thái có thể có của phiên người dùng (Người dùng có phiên hoặc người dùng không có phiên). Nếu người dùng không có phiên, điều hướng đến tệp chỉ mục của ứng dụng sẽ tạo phiên mới và lưu trữ một số dữ liệu giả. Nếu người dùng có một phiên hợp lệ (không hết hạn), tuyến đường sẽ hiển thị dữ liệu của phiên đó.

Bước 4 - Triển khai

Bây giờ bạn đã triển khai phiên sử dụng Upstash, bạn có thể tự do chọn bất kỳ chiến lược triển khai nào bạn chọn.

Đừng quên thiết lập các biến môi trường Upstash của bạn.

Phụ lục

Sử dụng createFileSessionStorage để phát triển cục bộ và createUpstashSessionStorage trong dàn dựng / sản xuất

Nó có khả năng muốn có thể phát triển trong khi ngoại tuyến. Khi phát triển cục bộ, bạn có thể thay thế createUpstashSessionStorage với createFileSessionStorage bằng cách phát hiện NODE_ENV hiện tại .

Sau khi kiểm tra việc triển khai Upstash của bạn có hoạt động hay không, bạn thay đổi sessions/upstash.server.ts tệp như sau:

Thay đổi phần này:

// from sessions/upstash.server.t

const { getSession, commitSession, destroySession } =
  createUpstashSessionStorage({ cookie: sessionCookie });

Với:

// from sessions/upstash.server.ts

const { getSession, commitSession, destroySession } = (process.env.NODE_ENV === "development") ?
createFileSessionStorage({ cookie: sessionCookie, dir: './sessions' });
:  createUpstashSessionStorage({ cookie: sessionCookie });

Bây giờ khi bạn phát triển cục bộ, bạn sẽ sử dụng hệ thống tệp cục bộ của mình thay vì gọi Upstash.

Kết luận

Trong bài đăng này, chúng tôi đã giới thiệu cách sử dụng Upstash Redis DB để lưu trữ dữ liệu lưu trữ phiên của chúng tôi. Remix API đóng gói quá trình triển khai lưu trữ phiên cụ thể thực sự tốt, giúp quá trình tích hợp trở nên dễ dàng hơn. Nếu bạn muốn chơi với ví dụ, bạn có thể xem nó trong mã nguồn Remix tại https://github.com/remix-run/remix/tree/main/examples/redis-upstash-session

Hãy tận hưởng.