搜尋
首頁web前端js教程使用 Permit.io 和 WebSockets 在聊天應用程式中進行即時授權

隨著現代聊天應用程式的發展,即時通訊需要越來越精細的存取控制。即時管理各種聊天室和參與者的動態權限,尤其是在複雜或多用戶環境中,很快就會變得具有挑戰性。如果您可以輕鬆地為您的聊天應用程式實現細粒度授權而不影響效能,結果會如何?

Permit.io 讓將強大的即時存取控制整合到您的聊天應用程式中變得簡單。透過將 Permit.io 的高級授權模型與 WebSocket 配對,您可以確保正確的使用者在正確的時間進行訪問,同時保持聊天應用程式所需的回應能力。

在本教程中,您將學習如何使用 Permit.io 在基於 WebSocket 的聊天應用程式中實現即時授權。最後,您將了解如何動態實施基於角色和基於屬性的存取控制,保護不同的聊天室、訊息可見性和即時互動。

聊天應用程式中的即時授權簡介

我們都以某種形式使用聊天應用程式來與朋友和家人保持聯繫,與同事討論重要事務,甚至開展業務。隨著對無縫、即時通訊的需求不斷增長,人們很容易認為保護這些互動的複雜安全措施是理所當然的。然而,隨著聊天應用程式變得越來越複雜,保護用戶資料和對話的挑戰也越來越大。細粒度的存取控制有助於確保只有授權使用者才能存取敏感資訊和操作。

為什麼即時聊天應用程式需要細粒度的存取控制

細粒度的存取控制對於即時聊天應用程式至關重要,以確保安全性、用戶自訂和法規遵循。
透過設定強大的身份驗證方法和基於角色的權限,聊天應用程式可以防止未經授權的使用者存取敏感對話,並允許管理員有效地管理使用者互動。這種方法還可以根據個人角色或偏好參與各種聊天類型(公共、私人或群組),從而增強用戶體驗,從而創建更具吸引力的互動。
此外,細粒度的存取控制可以幫助組織滿足嚴格的資料隱私法規(例如 GDPR),保護機密資料並最大程度地降低法律風險。

在聊天環境中實現動態授權的挑戰

這些要點涵蓋了段落中的所有主要思想。這是包含所有細節的精緻版本:

  1. 即時聊天應用程式需要即時權限檢查和更新,這使得動態授權具有挑戰性,同時又不會影響效能,尤其是在處理大量訊息和使用者時。
  2. 聊天應用程式通常涉及多個存取層,其權限根據角色、群組成員身份或特定屬性而變化,需要一致且高效的執行。
  3. 角色的動態變化(例如,管理員晉升、群組刪除或臨時存取)必須立即識別並應用於所有活動會話,而不會中斷正在進行的對話。
  4. 要實現這種程度的靈活性,同時保持無縫的使用者體驗,需要一個與 WebSocket 等即時協定緊密整合的高階授權模型。

概述 Permit.io 的授權解決方案如何使用 WebSocket 簡化此流程

Permit.io 的授權解決方案可以顯著簡化聊天應用程式中即時授權的實現,特別是與 WebSocket 整合時。以下概述了這種組合如何增強動態存取控制:

  1. 無縫整合: Permit.io 提供了一個強大的框架來管理細粒度的存取控制,可以輕鬆地將其整合到使用 WebSocket 的聊天應用程式中。這種整合允許即時權限檢查和更新,確保使用者可以根據其角色和屬性立即存取適當的聊天室和功能。
  2. 動態權限管理: 借助 Permit.io,開發人員可以實現適應使用者角色或群組成員資格變化的動態授權模型。例如,如果使用者被提升為管理員角色或暫時被授予特殊存取權限,這些變更可以立即反映在所有活動會話中,而不會中斷正在進行的對話。此功能透過確保即時一致地執行權限來解決動態授權的主要挑戰之一。
  3. 增強的性能: 透過利用 WebSocket 進行通信,Permit.io 確保即時授權過程不會損害應用程式效能。該架構支援大量訊息和用戶,允許高效處理並發存取請求,同時保持回應能力——這是聊天應用程式的關鍵要求。
  4. 基於角色和基於屬性的存取控制: Permit.io 有助於在聊天環境中實施基於角色和基於屬性的存取控制。這種靈活性允許管理員為不同的使用者類型(例如版主或普通使用者)定義特定權限,從而增強安全性,同時提供可自訂的使用者體驗。使用者可以根據分配的角色參與各種聊天類型 - 公共、私人或群組。
  5. 監理合規性: 實施 Permit.io 的解決方案可確保只有授權使用者才能存取聊天應用程式中的敏感資訊和功能,從而幫助組織滿足嚴格的資料隱私法規。這種合規性對於保護使用者資料並最大限度地減少與未經授權的存取相關的法律風險至關重要。

設定基於 WebSocket 的聊天應用程式

對於我們基於 Web 套接字的應用程序,我們將使用 Next.js 和 Ably,該服務使我們能夠輕鬆整合和管理由 Web 套接字支援的應用程式中的即時功能。

除了 Ably 和 Next Auth 之外,我們還可以使用 Firebase 之類的東西來處理身份驗證和即時功能。 Permit.io 部落格上有關於此內容的完整教學。

話不多說,我們繼續吧!

設定 Next.js

執行以下指令並依照指示操作:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

導航到新建立的專案資料夾並安裝一些我們將用於建立應用程式的軟體包:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

此外,從 Radix UI 安裝一些 UI 元件:

cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 

在專案根目錄下建立一個新檔案 - .prettierrc 並輸入以下內容:

npm install @radix-ui/react-scroll-area

在 tailwind.config.ts 檔案中,輸入以下內容:

{
  "plugins": ["prettier-plugin-tailwindcss"]
}
// ./tailwind.config.ts
import type { Config } from "tailwindcss";
import tailwindForms from "@tailwindcss/forms";
export default {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [tailwindForms],
} satisfies Config;

設定全域樣式

在 ./app/globals.css 檔案中,輸入以下內容:

In the `./next.config.ts`, enter the following:

// ./next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
  /* config options here */
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "lh3.googleusercontent.com",
      },
      {
        protocol: "https",
        hostname: "www.tapback.co",
      },
    ],
  },
};
export default nextConfig;

設定身份驗證

我們將使用 Auth.js,一個最初為 Next.js 建置的身份驗證函式庫。
執行以下命令來安裝軟體包:

/* ./app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
  body {
    @apply bg-white text-gray-800 dark:bg-gray-900 dark:text-gray-300;
  }
}
@layer components {
  .btn {
    @apply inline-flex items-center justify-center gap-2 rounded-full bg-gray-100 px-4 py-2 text-sm font-semibold text-gray-500 hover:brightness-95 focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2 dark:bg-gray-800 dark:text-gray-300 dark:brightness-105 dark:hover:bg-gray-700 dark:focus:ring-gray-800 dark:focus:ring-offset-gray-900;
  }
  .btn:has(> .icon:first-child) {
    @apply pl-2;
  }
  .btn:has(> .icon:last-child) {
    @apply pr-2;
  }
  .icon {
    @apply h-5 w-5 text-current;
  }
  .form-input {
    @apply flex grow rounded-full border border-none bg-gray-100 px-4 py-2 text-sm font-semibold text-gray-500 outline-none hover:brightness-95 focus:border-none focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2 dark:bg-gray-800 dark:text-gray-300 dark:brightness-105 dark:hover:bg-gray-700 dark:focus:ring-gray-800 dark:focus:ring-offset-gray-900;
  }
  .site-section {
    @apply py-16 md:py-24;
  }
  .site-section > .wrapper {
    @apply mx-auto max-w-5xl px-4 sm:px-6 lg:px-8;
  }
  .noscroll {
    @apply overflow-auto;
    scrollbar-width: none;
  }
}

我們必須建立一個 AUTH_SECRET 環境變數。該庫使用此隨機值來加密令牌和電子郵件驗證雜湊。 (請參閱部署以了解更多資訊)。您可以透過執行官方 Auth.js CLI 來產生一個:

npm install next-auth@beta

接下來,建立 Auth.js 設定檔和物件 - ./auth.js:

npx auth secret

? Created /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat/.env.local with `AUTH_SECRET`.

在 ./app/api/auth/[...nextauth]/route.ts 下新增路由處理程序:

// ./auth.ts
import NextAuth from "next-auth";
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [],
});

新增可選的中間件以保持會話處於活動狀態;這將在每次呼叫時更新會話過期時間 - ./middleware.ts:

// ./app/api/auth/[...nextauth]/route.ts

import { handlers } from "@/auth"; // Referring to the auth.ts we just created
export const { GET, POST } = handlers;

設定 Google OAuth

NextAuth 支援多個 OAuth 提供者進行身份驗證。在本教程中,我們將使用 Google。

要取得我們的 Google 用戶端 ID 和金鑰,我們必須在 Google Cloud Console 中設定一個新專案 - https://console.cloud.google.com/projectcreate

Google Cloud Console

接下來,在新建立的專案中,我們將設定一個新的同意畫面:

Consent Screen

建立同意畫面後,我們就可以設定憑證。從側邊欄導覽至憑證
按一下 建立憑證 按鈕,然後從下拉清單中選擇 OAuth 用戶端 ID

Oauth Client ID

在以下畫面中,選擇Web 應用程序, 輸入授權的JavaScript 來源,並重定向URI:http://localhost:3000 和http://localhost:3000/api/auth/callback /分別谷歌。

Create Oauth Client ID

這樣我們就應該擁有我們的客戶端 ID 和秘密:

Client ID and Secret

複製值並將其輸入到 .env 檔案中:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

接下來,在我們的 Auth.js 配置中啟用 Google 作為登入選項。我們必須從套件中匯入 Google 提供程序,並將其傳遞給我們先前在 Auth.js 設定檔中設定的提供者數組:

cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 

建立網站標題元件

讓我們為我們的應用程式建立一個包含登入和登出按鈕的標頭。建立一個新檔案 - ./components/Site/Header.tsx:

npm install @radix-ui/react-scroll-area

這裡,SiteHeader 元件充當主導覽列。

如果存在使用者會話(會話?.使用者),則顯示使用者的頭像、姓名和「退出」按鈕。
否則,顯示「登入」按鈕,並且由於我們使用 Next.js 伺服器操作,因此我們將其放入表單中。

登入和登出函數包裝在伺服器操作標記(「使用伺服器」)中,以便在 Next.js 中在伺服器端執行。

在我們的 ./app/layout.tsx 檔案中匯入 SiteHeader 元件:

{
  "plugins": ["prettier-plugin-tailwindcss"]
}

在首頁 ./app/page.tsx 中,輸入以下內容:

// ./tailwind.config.ts
import type { Config } from "tailwindcss";
import tailwindForms from "@tailwindcss/forms";
export default {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [tailwindForms],
} satisfies Config;

有了這個,我們應該有這樣的東西:

Auth with Google

現在我們已經設定了身份驗證,讓我們繼續使用 Ably 將 websockets 功能添加到我們的應用程式中。

使用 Ably 設定 WebSocket

要開始使用,請註冊 Ably,然後使用以下選項建立一個新應用程式

  • 應用程式名稱: 為您的應用程式取一個有意義的名字
  • 選擇您的首選語言: JavaScript
  • 您正在建立什麼類型的應用程式? 即時聊天

Ably App Set up

在下一個畫面中,複製您的 API 金鑰:

Ably API Key

將其保存在 .env 檔案中:

In the `./next.config.ts`, enter the following:

// ./next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
  /* config options here */
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "lh3.googleusercontent.com",
      },
      {
        protocol: "https",
        hostname: "www.tapback.co",
      },
    ],
  },
};
export default nextConfig;

在我們的應用程式中,安裝 Ably React SDK 和 JWT 的 jose 庫:

/* ./app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
  body {
    @apply bg-white text-gray-800 dark:bg-gray-900 dark:text-gray-300;
  }
}
@layer components {
  .btn {
    @apply inline-flex items-center justify-center gap-2 rounded-full bg-gray-100 px-4 py-2 text-sm font-semibold text-gray-500 hover:brightness-95 focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2 dark:bg-gray-800 dark:text-gray-300 dark:brightness-105 dark:hover:bg-gray-700 dark:focus:ring-gray-800 dark:focus:ring-offset-gray-900;
  }
  .btn:has(> .icon:first-child) {
    @apply pl-2;
  }
  .btn:has(> .icon:last-child) {
    @apply pr-2;
  }
  .icon {
    @apply h-5 w-5 text-current;
  }
  .form-input {
    @apply flex grow rounded-full border border-none bg-gray-100 px-4 py-2 text-sm font-semibold text-gray-500 outline-none hover:brightness-95 focus:border-none focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2 dark:bg-gray-800 dark:text-gray-300 dark:brightness-105 dark:hover:bg-gray-700 dark:focus:ring-gray-800 dark:focus:ring-offset-gray-900;
  }
  .site-section {
    @apply py-16 md:py-24;
  }
  .site-section > .wrapper {
    @apply mx-auto max-w-5xl px-4 sm:px-6 lg:px-8;
  }
  .noscroll {
    @apply overflow-auto;
    scrollbar-width: none;
  }
}

安裝 jose 和 ively 後,建立 ./app/api/ically/route.ts:

npm install next-auth@beta

讓我們來分解這裡發生的事情:

  1. JWT 令牌建立: createToken 函數產生與 Ably 相容的 JSON Web 令牌,包括使用者功能和用戶端識別碼。在這裡,我們將聲明編碼在令牌中,這表示 userClaim 將包含在該客戶端在名稱匹配的主題中發布的任何事件中。
  2. 動態功能:generateCapability 函數根據使用者的角色(主持人或一般使用者)為特定頻道指派權限。
  3. 使用者驗證:auth 函數用於檢索使用者的會話,確保只有經過驗證的使用者才能要求令牌。
  4. 環境變數: ABLY_SECRET_KEY 環境變數安全地儲存用於令牌簽署的 Ably API 金鑰。
  5. API 回應:處理程序處理請求,產生令牌,並將其作為 JSON 回應傳回,如果使用者未經驗證,則傳回空字串。

接下來,我們將建立該聊天頁面所需的所有元件。我們將從顯示用戶發送的單一訊息的訊息項目元件開始。

訊息項目組件

建立一個新檔案 - ./components/Message/Item.tsx:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

此 MessageItem 元件會根據 fromUser 屬性動態調整其佈局,並使用 flex-row-reverse 進行對齊。
它顯示來自 message.data.avatarUrl 的寄件者頭像。顯示訊息文字 (message.data.text) 及其時間戳記 (message.timestamp),格式為本地化時間字串。
對於目前使用者發送的訊息,有條件地顯示一個以 SVG 圖示呈現的刪除按鈕,並透過 message.id 觸發 onDelete 回呼。

訊息清單元件

建立一個新檔案 - ./components/Message/List.tsx:

cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 

MessageList 元件使用 messages.map() 循環呈現可捲動的訊息列表,其中每個訊息都透過 MessageItem 元件顯示。
它透過將會話電子郵件 (session.data.user.email) 與訊息的 clientId 進行比較,確定訊息是否是由登入使用者發送的,並使用 self-end 設計使用者訊息以實現右對齊。
每個 MessageItem 都會接收其訊息和 onDelete 回呼。

訊息輸入組件

建立新檔案 - ./components/Message/Input.tsx:

npm install @radix-ui/react-scroll-area

MessageInput 元件透過 useState 管理使用者輸入,並透過 onSubmit 提交訊息,提交後重設欄位。輸入欄位 () 顯示上下文佔位符,並在停用屬性為 true 時停用。

聊天頻道清單組件

建立一個新檔案 - ./components/Chat/ChannelList.tsx:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

ChatChannelList 元件將頻道清單呈現為連結。使用基於目前路徑名的 font-bold 類別來突出顯示活動通道。

聊天元件

建立一個新檔案 - ./components/Chat/index.tsx:

cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 

在這個組件中,我們做了一些事情:

  1. 訊息處理: 此元件透過 useChannel 監聽訊息(ADD、DELETE、PROMOTE)並相應地更新訊息清單。
  2. 發布訊息:使用publishMessage函數發布訊息,發送訊息文字和使用者頭像。
  3. ScrollArea: Radix UI 的 ScrollArea 用於訊息歷史記錄在垂直和水平方向上的平滑滾動。
  4. 訊息歷史記錄取得: 在掛載時,我們從頻道歷史記錄中取得最後 100 則訊息。

接下來,我們會將所有內容放在聊天頁面中。

建立聊天頁面

建立一個新檔案 - ./app/chat/[[...channel]]/page.tsx:

npm install @radix-ui/react-scroll-area

頁面元件將聊天應用程式包裝在提供者中以進行狀態和上下文管理。 SessionProvider 確保對使用者會話的全域訪問,而 AblyProvider 和 ChannelProvider 透過共用即時客戶端(authUrl:「/api/ically」)和當前頻道名稱(例如 chat:general)來實現與 Ably 的無縫整合。

佈局使用包含三個部分的網格:左側邊欄(用於頻道導航)、中心區域(用於訊息)和右側佔位符側邊欄(TODO:使用者清單)用於未來的功能,例如線上使用者。自動連接選項可確保 Ably 僅在瀏覽器中連接,避免 SSR 問題。

有了這個,當我們導航到 http://localhost:3000/chat/general:

時,我們應該有這樣的東西

Chat Interface

現在我們的茶

設定 Permit.io

在 https://www.permit.io/ 建立一個新帳號:

Create Permit Account

建立一個新項目

輸入您的專案名稱,在此範例中我將使用即時聊天

Create Permit Project

建立新資源

要為我們的聊天應用程式建立頻道,Permit 允許我們建立資源,這些資源是代表使用者可以存取的內容的實體,讓我們將頻道設定為資源以繼續:

Create new resource

編輯資源

現在我們可以編輯資源並在頻道資源上新增角色:

Edit Resource

查看角色

這是我們創造的角色。您可以前往政策頁面上的角色標籤查看。

View Roles

更新政策

現在我們可以更新我們的策略來決定誰有權存取每個資源的哪些內容:

Update Policies

建立資源實例

為聊天中我們想要的每個頻道建立資源實例,這裡我們為常規頻道建立一個實例,我們可以為隨機mod.

Create Resource Instance

查看實例

在這裡我們可以看到建立的資源實例:

View Instance

現在我們已經設定了 Permit Dashboard,我們可以將 Permit 添加到我們的 Next.js 應用程式中。

將 Permit.io 添加到您的 Next.js 應用程式

讓我們深入了解並開始將 Permit.io 整合到我們的應用程式中。

首先,我們必須安裝permitio套件:


npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 
我們必須從 Permit.io 儀表板取得 API 金鑰:

Obtain API Key

將複製的金鑰加入 .env 檔案:


cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 
設定本地 PDP

接下來,我們必須設定策略決策點,它是一個網路節點,負責使用策略和上下文資料回答授權查詢。

從 Docker Hub 拉取 PDP 容器(點擊此處安裝 Docker):


npm install @radix-ui/react-scroll-area
執行容器並將 PDP_API_KEY 環境變數替換為您的 API 金鑰。


{
  "plugins": ["prettier-plugin-tailwindcss"]
}
現在我們已經設定了PDP,讓我們深入了解向我們的應用程式添加autoriaztion,您可以透過Permit.io 上的分步教程了解有關將Permit.io 添加到Next.js 應用程式的更多信息部落格.

對於這個例子,我們需要設定一些可重複使用的函數和路由,讓我們從在 ./lib/permit.ts 中建立一個 Permit 函式庫函數開始:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

我們也會為所有與授權相關的實用函數建立 ./utils/permit.ts 檔案:

cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 

使用者掛鉤

我們必須建立一個 useUser 鉤子,這將使我們能夠輕鬆地在前端檢索許可使用者。建立一個新檔案./hooks/useUser.ts:

npm install @radix-ui/react-scroll-area

在身份驗證期間建立允許的用戶

要在登入期間自動將使用者新增至 Permit,請使用 NextAuth 的 signIn 回呼。回調期間:

  1. 取得資源實例:從 Permit 擷取資源實例(例如,預設工作區或專案)。
  2. 同步使用者資料:使用實用函數(如handleSyncUser)在Permit中建立或更新使用者資訊。這包括他們的 ID、電子郵件、姓名、角色(例如「參與者」)以及相關資源實例。
  3. 完成登入:傳回 true 後,登入程序將繼續。

用更新後的程式碼取代 ./auth.ts 檔案:

{
  "plugins": ["prettier-plugin-tailwindcss"]
}

這可確保使用者經過身份驗證並無縫整合到 Permit 中以進行存取控制。

如下所示,當使用者登入時,他們的帳戶將被添加到我們的許可儀表板中:

使用 Permit.io 和 WebSockets 在聊天應用程式中進行即時授權

在繼續之前,我們還需要設定一些東西,讓我們從類型開始,以便在開發應用程式時安撫 TypeScript。建立一個新的 ./types/user.ts 檔案並輸入以下內容:

// ./tailwind.config.ts
import type { Config } from "tailwindcss";
import tailwindForms from "@tailwindcss/forms";
export default {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [tailwindForms],
} satisfies Config;

接下來,我們將建立一些 API 路由來取得使用者資料和權限以及對使用者進行升級和降級。

取得用戶數據

建立一個新檔案 - ./app/api/permit/getUsers/route.ts:

In the `./next.config.ts`, enter the following:

// ./next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
  /* config options here */
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "lh3.googleusercontent.com",
      },
      {
        protocol: "https",
        hostname: "www.tapback.co",
      },
    ],
  },
};
export default nextConfig;

取得用戶數據

建立一個新檔案 *./app/api/permit/getUser/route.ts*:

/* ./app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
  body {
    @apply bg-white text-gray-800 dark:bg-gray-900 dark:text-gray-300;
  }
}
@layer components {
  .btn {
    @apply inline-flex items-center justify-center gap-2 rounded-full bg-gray-100 px-4 py-2 text-sm font-semibold text-gray-500 hover:brightness-95 focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2 dark:bg-gray-800 dark:text-gray-300 dark:brightness-105 dark:hover:bg-gray-700 dark:focus:ring-gray-800 dark:focus:ring-offset-gray-900;
  }
  .btn:has(> .icon:first-child) {
    @apply pl-2;
  }
  .btn:has(> .icon:last-child) {
    @apply pr-2;
  }
  .icon {
    @apply h-5 w-5 text-current;
  }
  .form-input {
    @apply flex grow rounded-full border border-none bg-gray-100 px-4 py-2 text-sm font-semibold text-gray-500 outline-none hover:brightness-95 focus:border-none focus:outline-none focus:ring-2 focus:ring-gray-200 focus:ring-offset-2 dark:bg-gray-800 dark:text-gray-300 dark:brightness-105 dark:hover:bg-gray-700 dark:focus:ring-gray-800 dark:focus:ring-offset-gray-900;
  }
  .site-section {
    @apply py-16 md:py-24;
  }
  .site-section > .wrapper {
    @apply mx-auto max-w-5xl px-4 sm:px-6 lg:px-8;
  }
  .noscroll {
    @apply overflow-auto;
    scrollbar-width: none;
  }
}

推廣用戶

建立一個新檔案 - ./app/api/permit/promoteUser/route.ts 並輸入以下內容:

npm install next-auth@beta

這裡有一個 Next.js API 路由,它透過使用 Permit.io 在不同資源實例上為使用者分配特定角色來提升使用者。
PromotionUser 函數檢查目前使用者是否有權限推廣其他用戶,並為指定頻道上的目標使用者指派「參與者」、「主持人」和「管理員」等角色。
GET 函數處理傳入請求、提取查詢參數、驗證它們、取得資源實例並執行升級過程。如果出現任何問題,它會以 JSON 回應的形式傳回結果或錯誤訊息。

降級用戶

建立一個新檔案 - ./app/api/permit/demoteUser/route.ts 並輸入以下內容:

npx create-next-app@latest live-chat
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- react
- react-dom
- next

Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
- @eslint/eslintrc


added 371 packages, and audited 372 packages in 1m

141 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
Initialized a git repository.

Success! Created live-chat at /Users/miracleio/Documents/writing/permit/real-time-authorization-in-a-chat-application-with-permitio-and-websockets/live-chat 

類似地,我們有一個 Next.js API 路由,它透過使用 Permit.io 取消分配使用者在特定資源實例上的角色來降級使用者。 demoteUser 函數刪除指定頻道上使用者的「參與者」、「主持人」和「管理員」等角色。 GET 函數處理傳入請求、提取查詢參數、驗證它們、取得資源實例、檢索使用者指派的角色並執行降級程序。

獲取資源

建立一個新檔案 - ./app/api/permit/listResourceInstances/route.ts 並輸入以下內容:

cd live-chat
npm install -D prettier prettier-plugin-tailwindcss  @tailwindcss/forms 

更新 Ably 權限路線

在我們的檔案 ./app/api/ously/route.ts 中,將其替換為以下更新的程式碼:

npm install @radix-ui/react-scroll-area

這裡我們合併了Permit.io來管理角色和權限,用基於角色的動態權限取代靜態設定。
generatePermissions 函數使用來自 Permit.io 的資料將角色對應到特定通道功能,確保權限與使用者角色即時保持一致。這種方法提高了靈活性,並確保系統適應角色或權限的變化,與 Ably 基於 JWT 的身份驗證無縫整合。

更新頻道列表

現在我們已經將資源(通道)添加到了許可儀表板中,我們可以從那裡獲取它們,而不是對它們進行硬編碼。
在 ./components/Chat/ChannelList.tsx 檔案中,進行以下變更:

{
  "plugins": ["prettier-plugin-tailwindcss"]
}

建立使用者清單組件

讓我們建立一個使用者清單元件,用於取得所有授權使用者並在使用者名稱旁邊顯示 升級降級 按鈕。
建立一個新檔案 - ./components/Chat/UserList.tsx 並輸入以下內容:

// ./tailwind.config.ts
import type { Config } from "tailwindcss";
import tailwindForms from "@tailwindcss/forms";
export default {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      colors: {
        background: "var(--background)",
        foreground: "var(--foreground)",
      },
    },
  },
  plugins: [tailwindForms],
} satisfies Config;

這裡,我們使用自訂鉤子 useUser 來獲取當前用戶的信息,並使用 Ably 的 useChannel 鉤子進行即時通道通訊。 getUserList 函數使用 Permit.io API 從伺服器取得使用者清單。此元件訂閱 Ably 通道進行即時更新,並在發生升級/降級事件時取得更新的使用者清單。使用者清單儲存在元件的狀態中,不包括目前使用者。

最後,我們可以將其新增到我們的頁面,在 ./app/chat/[[...channel]]/page.tsx 中:

In the `./next.config.ts`, enter the following:

// ./next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
  /* config options here */
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "lh3.googleusercontent.com",
      },
      {
        protocol: "https",
        hostname: "www.tapback.co",
      },
    ],
  },
};
export default nextConfig;

這樣我們應該能夠即時提升和降級用戶:

Real Time 使用 Permit.io 和 WebSockets 在聊天應用程式中進行即時授權

這是實際降級:

使用 Permit.io 和 WebSockets 在聊天應用程式中進行即時授權tion Action

結束語和結論

建立具有即時授權的聊天應用程式是一個充滿挑戰但有益的過程。透過整合 Permit.io 和 WebSockets 等強大的工具,您可以創建無縫體驗,確保安全且細粒度的存取控制。在本文中,我們探討了動態授權在聊天應用程式中的重要性,使用 Ably 建立了基於 WebSocket 的架構,並整合 Permit.io 進行授權管理。

此工作流程展示了現代工具如何簡化曾經複雜的實現,使開發人員能夠更多地關注用戶體驗和可擴展性,而不是底層基礎設施。透過正確的方法,您可以確保您的聊天應用程式既動態又安全。

進一步閱讀和資源

  • GitHub 程式碼 - https://github.com/miracleonyenma/live-chat
  • Permit.io 文件 – Permit.io 功能和 API 的綜合指南。
  • Ably WebSockets 文件 – 了解更多有關使用 Ably 建立即時應用程式的資訊。
  • Next.js 文件 – 探索使用 Next.js 建立 React 應用程式的進階功能。
  • Auth.js 文件 – 在 Next.js 應用程式中設定安全且可擴充的身份驗證。
  • 用於即時 Web 應用程式的 WebSockets – WebSockets 及其用例的深入概述。

下一步

基礎設定完成後,您可以探索簡單且進階的功能,例如:

  • 允許主持人刪除參與者訊息
  • 加入人工智慧驅動的審核工具來偵測和防止聊天中的濫用內容。您可以了解有關使用許可建立 AI 應用程式的更多信息
  • 實施分析儀表板來追蹤使用者活動和訊息趨勢。

以上是使用 Permit.io 和 WebSockets 在聊天應用程式中進行即時授權的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能