Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้างระบบแสดงความคิดเห็นที่ปลอดภัยสำหรับบล็อก Next.js ของคุณด้วย Redis และ NextAuth

เราจะสร้างส่วนความคิดเห็นสำหรับบล็อกของคุณในบทช่วยสอนนี้ กลุ่มเทคโนโลยีที่เราจะเป็น:

  1. NextJS 13 (ใน App dir)
  2. NextAuth (สำหรับการตรวจสอบสิทธิ์)
  3. Upstash Redis (สำหรับจัดเก็บความคิดเห็น)
  4. SWR (สำหรับการแคชและการตรวจสอบความคิดเห็นอีกครั้ง)

เริ่มกันเลย

การจัดการการรับรองความถูกต้องด้วย NextAuth

ประการแรกเราไม่สามารถปล่อยให้ใครแสดงความคิดเห็นได้ใช่ไหม? บางคนสามารถเรียกใช้สคริปต์เพื่อสแปมบล็อกของคุณด้วยความคิดเห็นได้ ขั้นแรกเรามาสร้างระบบการรับรองความถูกต้องก่อนที่จะให้ผู้อื่นแสดงความคิดเห็น เราจะใช้ NextAuth

ติดตั้ง 04 ในโครงการของคุณ

pnpm install next-auth

นี่คือโครงสร้างไดเรกทอรีภายใน App Directory

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

ตั้งค่าเส้นทาง Auth API ของเรา:

// 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 };

สร้างแอปพลิเคชัน Github OAuth ใหม่จากที่นี่เพื่อรับ 11 และ 26 .

สร้างระบบแสดงความคิดเห็นที่ปลอดภัยสำหรับบล็อก Next.js ของคุณด้วย Redis และ NextAuth

ตอนนี้ NextAuth ช่วยให้คุณสามารถลงชื่อเข้าใช้และออกจากระบบจากส่วนประกอบไคลเอ็นต์ใดๆ โดยใช้ 31 และ 43 ฟังก์ชั่นจาก 56 . แต่ก่อนหน้านั้น คุณต้องตั้งค่า Context Provider ซึ่งจะรวมแอปพลิเคชันทั้งหมดของคุณไว้

// 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>
 );
}

62 จะช่วยให้คุณสามารถเข้าถึงสถานะเซสชันจากส่วนประกอบไคลเอนต์ใด ๆ ในแอปพลิเคชัน

คุณสามารถเข้าถึงสถานะเซสชันได้โดยใช้ 76 ขอจาก 83 . นี่คือตัวอย่างสำหรับปุ่มเข้าสู่ระบบ:

"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>
 );
}

ด้วยเหตุนี้ ระบบการตรวจสอบสิทธิ์ของเราจึงพร้อมใช้งาน ตอนนี้เรามาเริ่มเส้นทางฝั่งเซิร์ฟเวอร์เพื่อจัดเก็บความคิดเห็นในฐานข้อมูล Redis กันดีกว่า

การตั้งค่าฐานข้อมูล Redis

  1. ไปที่ Upstash และสร้างฐานข้อมูล Redis
  2. เลือกภูมิภาคที่ใกล้กับผู้ใช้ของคุณและเลือกการเข้ารหัส TLS
  3. ติดตั้ง 94 แพ็คเกจ
pnpm install @upstash/redis

สร้างระบบแสดงความคิดเห็นที่ปลอดภัยสำหรับบล็อก Next.js ของคุณด้วย Redis และ NextAuth

  1. คัดลอกโทเค็นเหล่านี้ใน 109 ของคุณ .

มาเขียนจุดสิ้นสุด API ของเราในโครงสร้างไดเร็กทอรีนี้:

.
├── app
│ ├── api
│ │ ├── auth
│ │ │ └── [...nextauth]
│ │ │ └── route.ts
│ │ ├── comment
│ │ │ ├── delete
│ │ │ │ └── route.ts
│ │ │ ├── get
│ │ │ │ └── route.ts
│ │ │ └── post
│ │ │ └── route.ts
│ │ └── lib
│ │ ├── getUser.ts
│ │ └── redis.ts
  1. สร้างอินสแตนซ์ไคลเอ็นต์ 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;

นั่นก็คือมัน ขณะนี้ไคลเอนต์ Redis ของเราได้รับการตั้งค่าแล้ว และสิ่งที่เหลืออยู่คือการตั้งค่า APIroutes ในแอปพลิเคชันของเรา

เราจะใช้รายการ Redis เพื่อจัดเก็บความคิดเห็น พวกเขาสามารถทำหน้าที่เป็นสแต็กเพื่อให้ความคิดเห็นล่าสุดปรากฏที่ด้านบน แน่นอนว่าเรายังใช้ตรรกะการเรียงลำดับฝั่งไคลเอ็นต์ได้ แต่เมื่อ Redis มีโครงสร้างข้อมูลนี้อยู่แล้ว ก็ลองใช้เลย

คุณสามารถดูรหัสทั้งหมดได้ที่นี่ นี่คือส่วนสำคัญของมัน:

  1. สร้างความคิดเห็น:116 . สิ่งนี้จะผลักดันความคิดเห็นในรายการที่มีคีย์ 126

  2. รับความคิดเห็นทั้งหมด 135

  3. ลบความคิดเห็น 148 . การดำเนินการนี้จะลบรายการ 158 ทั้งหมด ในรายการด้วยคีย์ 162 .

API ของเราพร้อมใช้งานแล้ว มาเริ่มบูรณาการส่วนหน้ากับส่วนหลังกันดีกว่า

การตั้งค่าฝั่งไคลเอ็นต์

มันไม่ใช่เรื่องยากเลย เราเพียงแค่ต้องเข้าถึงจุดสิ้นสุดที่เราเพิ่งสร้างขึ้นโดยใช้ 176 เราจะใช้ไลบรารีชื่อ 181 สำหรับการแคชและการตรวจสอบความคิดเห็นอีกครั้ง แต่อย่าลังเลที่จะใช้ไลบรารีอื่นเช่น React Query เพื่อมัน

เราสร้าง 192 hook ซึ่งจะมี 201 และ 214 ตัวจัดการสำหรับการร้องขอ

"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;

ตอนนี้ส่วนความคิดเห็นของเราเสร็จสิ้นแล้ว เราสามารถดึงข้อมูล โพสต์ และลบความคิดเห็นได้ ขั้นตอนต่อไปคือการสร้างส่วนประกอบสำหรับกล่องความคิดเห็นและรายการความคิดเห็น นี่คือตัวอย่างที่สมบูรณ์