Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Redis

Tạo hệ thống nhận xét an toàn cho blog Next.js của bạn với Redis &NextAuth

Chúng tôi sẽ xây dựng phần bình luận cho blog của bạn trong hướng dẫn này️. Nhóm công nghệ chúng tôi sẽ là:

  1. NextJS 13 (trong thư mục ứng dụng)
  2. NextAuth (để xác thực)
  3. Upstash Redis (để lưu trữ nhận xét)
  4. SWR (để lưu vào bộ nhớ đệm và xác thực lại nhận xét)

Hãy bắt đầu.

Xử lý xác thực bằng NextAuth

Đầu tiên, chúng ta không thể để bất cứ ai gửi bình luận, phải không? Ai đó có thể chạy một đoạn script để gửi bình luận vào blog của bạn. Trước tiên hãy xây dựng hệ thống Xác thực trước khi cho phép mọi người đăng bình luận. Chúng tôi sẽ sử dụng NextAuth.

Cài đặt next-auth trong dự án của bạn.

pnpm install next-auth

Đây là cấu trúc thư mục bên trong Thư mục ứng dụng

.
├── app
│ ├── api
│ │ └── auth
│ │ └── [...nextauth]
│ │ └── route.ts
│ ├── blog
│ │ ├── page.tsx
│ │ └── [...slug]
│ │ └── page.tsx
│ ├── components
│ │ └── LoginButton.tsx
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx

Thiết lập lộ trình API xác thực của chúng tôi:

// app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";
 
const handler = NextAuth({
 providers: [
 GithubProvider({
 clientId: process.env.GITHUB_CLIENT_ID!,
 clientSecret: process.env.GITHUB_CLIENT_SECRET!,
 }),
 ],
 callbacks: {
 async session({ session, token }) {
 if (session && session.user && token.sub) {
 session.user.sub = token.sub;
 }
 return session;
 },
 },
});
 
export { handler as GET, handler as POST };

Tạo một ứng dụng Github OAuth mới từ đây để nhận GITHUB_CLIENT_IDGITHUB_CLIENT_SECRET .

Tạo hệ thống nhận xét an toàn cho blog Next.js của bạn với Redis &NextAuth

Giờ đây, NextAuth cho phép bạn Đăng nhập và Đăng xuất từ bất kỳ Thành phần ứng dụng khách nào bằng cách sử dụng signInsignOut chức năng từ next-auth . Nhưng trước đó, bạn cần thiết lập Nhà cung cấp ngữ cảnh để bao bọc toàn bộ ứng dụng của bạn.

// app/layout.tsx
"use client";
 
import "./globals.css";
 
import { SessionProvider } from "next-auth/react";
 
export default function RootLayout({
 children,
}: {
 children: React.ReactNode;
}) {
 return (
 <html lang="en">
 <SessionProvider>
 <body>{children}</body>
 </SessionProvider>
 </html>
 );
}

SessionProvider sẽ cho phép bạn truy cập trạng thái phiên từ bất kỳ thành phần Máy khách nào trong ứng dụng.

Bạn có thể truy cập trạng thái phiên bằng useSession móc từ next-auth . Đây là mẫu cho Nút đăng nhập:

"use Client";
 
import { signIn, signOut, useSession } from "next-auth/react";
 
export default function LoginButton() {
 const { data: session } = useSession();
 if (session) {
 return (
 <div>
 Signed in as {session.user?.name} using {session.user?.email} <br />
 <button onClick={() => signOut()}>Sign out</button>
 </div>
 );
 }
 return (
 <div>
 Not signed in <br />
 <button onClick={() => signIn()}> Sign in </button>
 </div>
 );
}

Với điều này, hệ thống Auth của chúng tôi đã sẵn sàng. Bây giờ, hãy bắt đầu các lộ trình phía máy chủ để lưu trữ nhận xét trong cơ sở dữ liệu Redis.

Thiết lập cơ sở dữ liệu Redis

  1. Truy cập Upstash và tạo Cơ sở dữ liệu Redis.
  2. Chọn khu vực gần người dùng của bạn và chọn mã hóa TLS.
  3. Cài đặt @upstash/redis gói.
pnpm install @upstash/redis

Tạo hệ thống nhận xét an toàn cho blog Next.js của bạn với Redis &NextAuth

  1. Sao chép các mã thông báo này vào .env.local của bạn .

Bây giờ hãy viết các điểm cuối API của chúng tôi trong cấu trúc thư mục này:

.
├── app
│ ├── api
│ │ ├── auth
│ │ │ └── [...nextauth]
│ │ │ └── route.ts
│ │ ├── comment
│ │ │ ├── delete
│ │ │ │ └── route.ts
│ │ │ ├── get
│ │ │ │ └── route.ts
│ │ │ └── post
│ │ │ └── route.ts
│ │ └── lib
│ │ ├── getUser.ts
│ │ └── redis.ts
  1. Tạo phiên bản máy khách Redis
// app/api/lib/redis.ts
import { Redis } from "@upstash/redis";
 
/*
This tries to load UPSTASH_REDIS_REST_URL
and UPSTASH_REDIS_REST_TOKEN from your environment
using process.env
*/
const redis = Redis.fromEnv();
 
export default redis;

Đó là nó. Ứng dụng Redis của chúng tôi hiện đã được thiết lập và tất cả những gì còn lại là thiết lập các APIroutes cho nó trong ứng dụng của chúng tôi.

Chúng tôi sẽ sử dụng Danh sách Redis để lưu trữ các nhận xét. Chúng có thể hoạt động như một ngăn xếp để bình luận gần đây nhất được hiển thị ở trên cùng. Chắc chắn, chúng ta cũng có thể triển khai phía máy khách logic sắp xếp nhưng khi Redis đã cung cấp cấu trúc dữ liệu này thì hãy sử dụng nó.

Bạn có thể xem toàn bộ mã ở đây. Đây là ý chính của nó:

  1. Tạo một bình luận:redis.lpush(referer, comment) . Điều này sẽ đẩy nhận xét vào danh sáchcó khóa referer

  2. Nhận tất cả các bình luận redis.lrange(referer, 0, -1)

  3. Xóa bình luận redis.lrem(referer, 0, comment) . Thao tác này sẽ xóa tất cả các lần xuất hiện của comment trong danh sách có khóa referer .

API của chúng tôi hiện đã sẵn sàng. Hãy bắt đầu tích hợp giao diện người dùng với phần phụ trợ.

Thiết lập phía máy khách

Nó không khó lắm đâu. Chúng ta chỉ cần đạt các điểm cuối mà chúng ta vừa tạo bằng fetch .Chúng tôi sẽ sử dụng thư viện có tên swr để lưu vào bộ nhớ đệm và xác nhận lại các nhận xét. Nhưng bạn có thể thoải mái sử dụng các thư viện khác như React Query cho nó.

Chúng tôi tạo useComment() hook sẽ có onSubmit()onDelete() trình xử lý để thực hiện yêu cầu.

"use client";
 
import { useState } from "react";
 
import type { Comment } from "@/app/interfaces/interfaces";
import useSWR from "swr";
 
const fetcher = (url: string) => fetch(url).then((res) => res.json());
 
const useComment = () => {
 const [text, setText] = useState("");
 const { data: comments, mutate } = useSWR<Comment[]>(
 "/api/comment/get",
 fetcher,
 {
 fallbackData: [],
 },
 );
 const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
 e.preventDefault();
 try {
 await fetch("/api/comment/post", {
 method: "POST",
 body: JSON.stringify({ text }),
 headers: {
 "Content-Type": "application/json",
 },
 });
 setText("");
 await mutate();
 } catch (error) {
 console.log(error);
 }
 };
 const onDelete = async (comment: Comment) => {
 try {
 await fetch("/api/comment/delete", {
 method: "POST",
 body: JSON.stringify({ comment }),
 headers: {
 "Content-Type": "application/json",
 },
 });
 await mutate();
 } catch (error) {
 console.log(error);
 }
 };
 return { text, setText, comments, onSubmit, onDelete };
};
 
export default useComment;

Bây giờ phần Comment của chúng ta đã xong. Chúng tôi có thể tìm nạp, đăng và xóa bình luận. Các bước tiếp theo sẽ là tạo các thành phần cho hộp Bình luận và danh sách bình luận. Đây là mẫu hoàn chỉnh