搜索
首页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中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

自定义Google搜索API设置教程自定义Google搜索API设置教程Mar 04, 2025 am 01:06 AM

本教程向您展示了如何将自定义的Google搜索API集成到您的博客或网站中,提供了比标准WordPress主题搜索功能更精致的搜索体验。 令人惊讶的是简单!您将能够将搜索限制为Y

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

示例颜色json文件示例颜色json文件Mar 03, 2025 am 12:35 AM

本文系列在2017年中期进行了最新信息和新示例。 在此JSON示例中,我们将研究如何使用JSON格式将简单值存储在文件中。 使用键值对符号,我们可以存储任何类型的

8令人惊叹的jQuery页面布局插件8令人惊叹的jQuery页面布局插件Mar 06, 2025 am 12:48 AM

利用轻松的网页布局:8个基本插件 jQuery大大简化了网页布局。 本文重点介绍了简化该过程的八个功能强大的JQuery插件,对于手动网站创建特别有用

什么是这个'在JavaScript?什么是这个'在JavaScript?Mar 04, 2025 am 01:15 AM

核心要点 JavaScript 中的 this 通常指代“拥有”该方法的对象,但具体取决于函数的调用方式。 没有当前对象时,this 指代全局对象。在 Web 浏览器中,它由 window 表示。 调用函数时,this 保持全局对象;但调用对象构造函数或其任何方法时,this 指代对象的实例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。这些方法使用给定的 this 值和参数调用函数。 JavaScript 是一门优秀的编程语言。几年前,这句话可

通过来源查看器提高您的jQuery知识通过来源查看器提高您的jQuery知识Mar 05, 2025 am 12:54 AM

jQuery是一个很棒的JavaScript框架。但是,与任何图书馆一样,有时有必要在引擎盖下发现发生了什么。也许是因为您正在追踪一个错误,或者只是对jQuery如何实现特定UI感到好奇

10张移动秘籍用于移动开发10张移动秘籍用于移动开发Mar 05, 2025 am 12:43 AM

该帖子编写了有用的作弊表,参考指南,快速食谱以及用于Android,BlackBerry和iPhone应用程序开发的代码片段。 没有开发人员应该没有他们! 触摸手势参考指南(PDF) Desig的宝贵资源

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无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器