拓冰建站拓冰建站
首页 / 资讯中心 / 正文

使用 @novu/react 为 React 应用集成 Novu Inbox 通知中心:从 Keyless 快速体验到 HMAC 安全加固

使用 novu/react 为 React 应用集成 Novu Inbox 通知中心从 Keyless 快速体验到 HMAC 安全加固【免费下载链接】novuThe open-source communication infrastructure for agents and products项目地址: https://gitcode.com/GitHub_Trending/no/novunovu/react是 Novu 官方发布的 React SDK核心交付物是一个开箱即用的Inbox /通知中心组件可在几分钟内为 React 应用接入完整的应用内通知能力未读角标、通知列表、实时推送、偏好设置等。本文以 packages/react/README.md 为主线结合仓库源码系统讲解安装、Keyless 快速试用、真实订阅者接入、自定义后端地址、受控开关、本地化以及 HMAC 加密安全机制帮助你快速落地一个生产可用的应用内通知中心。安装与包结构在 React 应用中安装novu/react仅需一条命令npm install novu/react从 packages/react/package.json 可以看到该包当前版本为3.19.2其 peerDependencies 要求react与react-dom为^18.0.0 || ^19.0.0 || ^19.0.0-0react-dom为可选底层唯一的核心依赖是novu/jsworkspace 引用。包通过exports字段提供了多个子路径入口novu/react默认入口浏览器端 ESM/CJSnovu/react/hooks——仅引入 Hooks适合自定义 UI 场景novu/react/themes——主题变量novu/react/server——服务端渲染相关入口novu/react/internal——内部 API从 packages/react/src/index.ts 的导出清单看SDK 除Inbox外还导出Bell、Notifications、Preferences、NovuProvider等组件以及useNotifications、useCounts、usePreferences、useSubscription等 Hooks本文聚焦 README 主线中的Inbox /用法。Keyless 模式零配置秒级体验Keyless 模式专为本地测试与快速实验设计无需任何环境配置直接引入并渲染Inbox /即可看到完整的通知中心界面。import React from react; import { Inbox } from novu/react; export function App() { return Inbox /; }这一模式在源码中有明确的实现支撑。查看 Inbox.tsx 可以看到注释for keyless we provide an empty string, the api will generate a identifier——当未传入applicationIdentifier时SDK 会以空字符串占位在 session.ts 中会话初始化后若服务端返回以pk_keyless_前缀开头的应用标识符SDK 会将其存入localStorage并在后续会话中复用从而实现免配置的持续体验。对应地types.ts 中subscriber、subscriberId、applicationIdentifier三者均可缺省的类型分支就是 Keyless 模式。连接真实订阅者applicationIdentifier 与 subscriber要把通知中心接入你的 Novu 环境和真实用户需要传入两个关键属性applicationIdentifier应用标识符相当于 API 通信的公钥可在 Novu Dashboard 的 API Keys 页面获取subscriber订阅者 ID即你业务系统中用户的唯一标识通常是数据库中的用户 ID。import { Inbox } from novu/react; function Novu() { return ( Inbox subscriberSUBSCRIBER_ID applicationIdentifierAPPLICATION_IDENTIFIER / ); }需要注意subscriber与subscriberId在类型上是互斥的types.ts 中subscriberId被标记为deprecated兼容历史版本见 NV-5801推荐统一使用subscriberprop。在 Inbox.tsx 中SDK 会通过buildSubscriber将两者归一化为标准Subscriber对象再交给InternalNovuProvider创建Novu实例最终在session.initialize阶段带上subscriberId与浏览器时区见 session.ts与服务端建立会话。自定义后端与 Socket 地址默认情况下SDK 使用 Novu 托管的 API 与 Socket 服务。在自托管self-hosted场景中可以通过backendUrl与socketUrl覆盖默认地址import { Inbox } from novu/react; function Novu() { return ( Inbox backendUrlYOUR_BACKEND_URL socketUrlYOUR_SOCKET_URL subscriberSUBSCRIBER_ID applicationIdentifierAPPLICATION_IDENTIFIER / ); }这两个属性连同socketOptions如自定义重连策略、apiUrl等一起被组装进NovuOptions见 Inbox.tsx在 NovuProvider.tsx 中传给底层new Novu({ ... })构造器。若你的 Novu 实例由上层NovuProvider统一提供Inbox会通过useUnsafeNovu直接复用该实例避免重复初始化。受控 Inbox用 open 属性管理弹层状态默认的 Inbox 弹层popover由组件内部管理开关。如果希望完全掌控开关时机例如在导航栏的按钮上控制可以传入open属性实现受控模式import { Inbox } from novu/react; function Novu() { const [open, setOpen] useState(false); return ( div Inbox subscriberSUBSCRIBER_ID applicationIdentifierAPPLICATION_IDENTIFIER open{isOpen} / button onClick{() setOpen(true)}Open Inbox/button button onClick{() setOpen(false)}Close Inbox/button /div ); }open只是DefaultInboxProps中的可选布尔属性之一。结合 types.tsInbox /还支持placement弹层位置与placementOffset偏移量以及一系列渲染回调renderNotification整体自定义通知项、renderAvatar/renderSubject/renderBody分别定制头像、标题与正文、renderDefaultActions/renderCustomActions默认/自定义操作按钮、renderBell自定义铃铛和点击回调onNotificationClick、onPrimaryActionClick、onSecondaryActionClick。这些回调通过 Renderer.tsx 与 NovuUI.tsx 中的mountComponent机制注入到底层 UI 引擎实现 React 渲染与声明式 UI 的双向桥接。本地化localization 属性通过localization属性可以替换 Inbox 界面文案支持任意语言import { Inbox } from novu/react; function Novu() { return ( Inbox subscriberSUBSCRIBER_ID applicationIdentifierAPPLICATION_IDENTIFIER localization{{ inbox.status.archived: Archived, inbox.status.unread: Unread, inbox.status.options.archived: Archived, inbox.status.options.unread: Unread, inbox.status.options.unreadRead: Unread/Read, inbox.status.unreadRead: Unread/Read, inbox.title: Inbox, notifications.emptyNotice: No notifications, locale: en-US, }} / ); }localization的类型InboxLocalization由novu/js/ui定义并从 index.ts 重新导出覆盖通知列表状态未读/已读/归档、标题、空状态提示、操作项等多个文案键locale键则用于指定日期等本地化格式。运行时该对象会在 NovuUI.tsx 中通过novuUI.updateLocalization(options.localization)动态下发给 UI 引擎无需重新挂载组件即可生效。HMAC 加密防止订阅者身份伪造为什么需要 HMACapplicationIdentifier是公开的公钥任何拿到它的人都可以直接调用 API。如果攻击者把请求中的subscriberId换成其他用户的 ID就能越权读取他人的通知流。HMACHash-Based Message Authentication Codes加密用你的**服务端密钥API Key**对subscriberId进行签名使服务端能够校验该订阅者 ID 是否由你的后端合法签发从而杜绝恶意用户冒充他人。启用 HMAC 加密在 Novu 管理后台的In-App应用内设置页面为当前环境开启 HMAC encryption 即可。订阅者 HMAC服务端生成、客户端携带在服务端Node.js使用密钥对subscriberId生成 SHA-256 HMAC 十六进制摘要import { createHmac } from crypto; const subscriberHash createHmac(sha256, process.env.NOVU_API_KEY).update(subscriberId).digest(hex);然后将明文subscriberId与哈希值一并传给客户端组件Inbox subscriber{SUBSCRIBER_ID_PLAIN_VALUE} subscriberHash{SUBSCRIBER_ID_HASH_VALUE} applicationIdentifier{APPLICATION_IDENTIFIER} /注意如果 In-App 提供商设置中已启用 HMAC 加密而subscriberHash与subscriberId未同时提供Inbox 将无法加载。从实现上看subscriberHash会一路传递到会话初始化在 session.ts 中subscriberHash与contextHash被原样送入initializeSession请求体由服务端用密钥重新计算比对校验通过后才建立会话。Context HMAC保护附加数据可选如果通过context属性传递附加数据如租户信息、环境标识等攻击者同样可能篡改这些数据因此需要额外生成contextHashimport { createHmac } from crypto; import { canonicalize } from tufjs/canonical-json; const context { tenant: acme, app: dashboard }; const contextHash createHmac(sha256, process.env.NOVU_API_KEY) .update(canonicalize(context)) .digest(hex);把context与contextHash一起传给组件Inbox subscriber{SUBSCRIBER_ID_PLAIN_VALUE} subscriberHash{SUBSCRIBER_ID_HASH_VALUE} context{{ tenant: acme, app: dashboard }} contextHash{CONTEXT_HASH_VALUE} applicationIdentifier{APPLICATION_IDENTIFIER} /注意启用 HMAC 加密且提供了context时contextHash为必填。由于使用tufjs/canonical-json做规范化序列化哈希与键的顺序无关——{a:1, b:2}与{b:2, a:1}会生成相同的哈希服务端与客户端按同一规则计算即可稳定比对。在 types.ts 中subscriberHash与contextHash均为可选字符串属性二者在 Inbox.tsx 中进入providerProps最终成为NovuOptions的一部分。SDK 侧并不自行计算哈希——签名计算必须在持有密钥的服务端完成密钥绝不可下发到浏览器端。进阶从组件到 Hooks 的自由度README 的核心是Inbox /开箱即用组件如果需要完全自研 UInovu/react/hooks子路径提供了数据层 Hooks。例如 useNotifications.ts 支持按tags、read、archived、seen、severity、createdGte/createdLte等条件过滤拉取通知返回notifications、isLoading、hasMore以及readAll、seenAll、archiveAll、archiveAllRead、refetch、fetchMore等操作useCounts.ts 则通过filters数组统计各类未读/未读数。两者都默认通过 WebSocket 监听notifications.notification_received、notifications.unread_count_changed等事件实时更新也可传入realtime: false关闭内置实时订阅、改用refetch()自行驱动对应NovuProvider的realtime配置见 NovuProvider.tsx。这正是 docs/platform/quickstart/react.mdx 中10 分钟接入 React 实时应用内通知能力背后的数据层基础。小结novu/react的Inbox /用最少的代码覆盖了通知中心的完整闭环Keyless 模式用于快速验证applicationIdentifiersubscriber接入真实用户backendUrl/socketUrl适配自托管部署open属性实现受控弹层localization完成多语言HMAC 体系subscriberHashcontextHash则从身份与数据两个维度堵住越权与篡改风险。若默认 UI 无法满足定制需求还可借助render*回调与/hooks子路径逐步替换为完全自研的界面。【免费下载链接】novuThe open-source communication infrastructure for agents and products项目地址: https://gitcode.com/GitHub_Trending/no/novu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门