扣子Coze实现ChatSDK的会话隔离(纯前端,萌新必看)

项目背景

使用coze提供的代码在网页插入智能体后,发现不同用户之间没有实现会话隔离(可以互相看到对话记录)。

虽然官方文档里也给了解决方案 ,但写的很粗略,对低代码用户非常不友好,而且示例代码给的还是python的,岂不是说要再部署个后端才能实现。

本文提供一个前端实现用户隔离的方案。

实现原理

先来看官方提供的代码:

<script src="https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.2.0-beta.10/libs/cn/index.js"></script> <script> new CozeWebSDK.WebChatClient({ //创建一个智能体界面 config: { bot_id: '**********', // 智能体ID }, componentProps: { title: 'Coze', }, auth: { type: 'token', token: 'pat_********', // 访问令牌 onRefreshToken: function () { return 'pat_********' // 备用访问令牌,可以不填 } } }); </script>

由于coze是根据令牌来区分对话记录,而我们又把令牌写死在代码里,导致所有用户使用的是同一个令牌,看到的就是相同的对话记录。

也就是说,只要给不同用户发不同的令牌,就可以实现用户隔离了。

我们可以使用coze提供的OAuth应用来为每个用户自动申请新令牌,完整流程见下图。

流程对比

前期准备

需要准备以下四个东西:

  • 智能体 ID
  • OAuth ID
  • OAuth 公钥
  • OAuth 私钥

智能体

创建并发布智能体,智能体ID可以在地址栏里找到。

点开智能体,ID在地址栏里

OAuth

创建OAuth应用,类型为服务类应用,保存应用ID。

创建OAuth应用,类型为服务类应用

权限勾选 "Bot管理"、"会话管理"、"文件"、"消息"

设置权限

点击创建Key,保存生成的公钥和私钥,私钥文件用记事本打开即可

创建密钥

完整代码

js代码:

// 加载JWT生成库并初始化Coze智能体,替换你的配置后,加到网页的js里 (function() { // 配置参数(替换为你的实际信息) const COZE_CONFIG = { botId: '1145141145141', //智能体 ID appId: '*************',//OAuth ID publicKey: '******************************************************', //OAuth 公钥 privateKey:`-----BEGIN PRIVATE KEY----- ****************************************************** ****************************************************** -----END PRIVATE KEY-----` //OAuth 私钥,全复制进来 }; // 加载JWT库 function loadJwtLibrary() { return new Promise((resolve, reject) => { // 检查是否加载成功 if (window.KJUR && window.KJUR.jws && window.KJUR.jws.JWS) { resolve(); return; } const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js'; script.type = 'text/javascript'; script.crossOrigin = 'anonymous'; // 处理跨域问题 // 加载成功回调 script.onload = () => { // 验证库是否正确加载 if (window.KJUR && window.KJUR.jws && window.KJUR.jws.JWS) { resolve(); } else { reject(new Error('JWT库加载但未正确初始化')); } }; // 加载失败回调 script.onerror = () => { reject(new Error(`JWT库加载失败,请检查链接: ${script.src}`)); }; document.head.appendChild(script); }); } // 生成符合Coze要求的JWT function generateCozeJwt(userUid) { const header = { alg: 'RS256', typ: 'JWT', kid: COZE_CONFIG.publicKey }; const currentTime = Math.floor(Date.now() / 1000); const payload = { iss: COZE_CONFIG.appId, aud: "api.coze.cn", jti: Math.random().toString(36).substr(2, 32) + Date.now(), iat: currentTime, exp: currentTime + 3600, session_name: userUid }; const formattedPublicKey = COZE_CONFIG.privateKey; return window.KJUR.jws.JWS.sign( header.alg, JSON.stringify(header), JSON.stringify(payload), formattedPublicKey ); } // 获得Token并创建Coze智能体界面 async function getAccessToken(jwt) { try { const response = await fetch("https://api.coze.cn/api/permission/oauth2/token", { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${jwt}` }, body: JSON.stringify({ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', duration_seconds: 900 }) }); if (!response.ok) { throw new Error(`获取token失败,HTTP状态码: ${response.status}`); } const data = await response.json(); new CozeWebSDK.WebChatClient({ config: { bot_id: COZE_CONFIG.botId }, componentProps: { title: 'Coze AI助手' }, auth: { type: 'token', token: data.access_token, onRefreshToken: () => data.access_token } }); } catch (error) { throw new Error(`获取Access Token失败: ${error.message}`); } } // 获取用户唯一标识 function getUserUid() { // 从本地存储获取登录用户ID const loggedUserId = localStorage.getItem('website_user_id'); if (loggedUserId) return loggedUserId; // 生成临时访客ID let visitorId = localStorage.getItem('coze_visitor_id'); if (!visitorId) { visitorId = `visitor_${Date.now()}_${Math.random().toString(36).slice(-6)}`; localStorage.setItem('coze_visitor_id', visitorId); } return visitorId; } // 初始化Coze聊天 function initCozeChat() { if (!window.CozeWebSDK || !window.CozeWebSDK.WebChatClient) { console.error('Coze SDK未加载'); return; } const userUid = getUserUid(); const jwtToken = generateCozeJwt(userUid); getAccessToken(jwtToken); } // 加载Coze SDK function loadCozeSdk() { const script = document.createElement('script'); script.src = "https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.2.0-beta.10/libs/cn/index.js"; script.onload = initCozeChat; script.onerror = () => console.error(`Coze SDK加载失败: ${COZE_CONFIG.sdkSrc}`); document.head.appendChild(script); } // 初始化流程 async function init() { try { await loadJwtLibrary(); loadCozeSdk(); } catch (error) { console.error('初始化失败:', error.message); } } // 页面加载完成后初始化 if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } })();

把测试网页也贴一下,创建一个txt文件,把代码复制进去,再重命名为index.html,双击打开就可以了。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Coze 智能体测试页面</title> </head> <body> <div> <div> <h1>Coze 智能体测试页面</h1> </div> </div> <script> //在此插入上述代码 </script> </body> </html>

成功的话应该会看到这样的界面,并且实现了用户对话隔离:

成功加载

安全问题

由于直接把公钥和私钥写在了js里,肯定有安全问题,但毕竟是全靠前端实现,不知道有啥解决方案( •̀ ω •́ )✧。

Read more

AI绘画效率革命:Z-Image-Turbo4步极速显影技术

AI绘画效率革命:Z-Image-Turbo 4步极速显影技术 引言 还在为生成一张高清AI图片等上几分钟甚至十几分钟吗?那种看着进度条缓慢爬升,或者中途因为显存不足而报错崩溃的体验,相信很多尝试过AI绘画的朋友都经历过。传统的扩散模型虽然效果惊艳,但动辄20步、50步的迭代计算,让“快速出图”成了一种奢望。 今天要介绍的 Z-Image-Turbo 极速云端创作室,就是为了解决这个痛点而生的。它搭载了与SDXL Turbo同源的加速引擎,将图像生成过程压缩到了惊人的 4步。这不仅仅是速度的提升,更是一种工作流的革新——从“等待渲染”到“立等可取”。想象一下,你输入一段描述,点击生成,几乎在眨眼之间,一张1024x1024的高清图片就呈现在你面前。无论是寻找灵感的概念设计师,还是需要快速产出素材的内容创作者,这都意味着效率的指数级飞跃。 本文将带你深入了解这项“4步极速显影”技术的核心原理,并手把手教你如何快速部署和使用这个镜像,体验真正的AI绘画效率革命。 1. 极速背后的技术核心:Turbo加速与稳定性保障 Z-Image-Turbo之所以能实现“秒级出图”,并非简

基于无人机遥感的植被覆盖度测量实践与经验分享

基于无人机遥感的植被覆盖度测量实践与经验分享

分享基于无人机遥感的植被覆盖度测量实验经验,主要任务是利用大疆Mavic 3无人机进行植被覆盖度地面测量,包含样方设计、航线规划、现场拍摄以及借助AI算法计算覆盖度。 一、实验概况与目的 实验测量的植被覆盖度(Fractional Vegetation Cover, FVC)定义为植被地上部分垂直投影面积占统计区总面积的百分比,是反映生态环境状态的重要参量,传统地面测量耗时耗力,而无人机遥感凭借其高机动性和高分辨率成为主流手段。本次实验的主要目的是: * 掌握无人机遥感监测的标准化操作流程 * 学习植被覆盖度地面测量的技术方法 * 熟悉使用AI(DeepSeek算法)完成植被覆盖度计算 * 总结无人机监测中的常见问题及解决方案二、技术方法与工作流程 二、技术方法与工作流程 2.1 植被覆盖度地面测量技术简介 植被覆盖度指单位面积内植被冠层(叶、茎、枝)垂直投影面积所占的比例。目前最常用的地面测量方法是照相法——利用数码相机或无人机拍摄样方照片,然后通过图像识别计算植被像素占比。本次实验采用无人机垂直向下拍摄小样方(1m×1m),再通过算法批量计算覆盖度。 2.

零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体

零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体

零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体 本文应用基于Rokid灵珠智能体/CXR SDK开发,开发指南https://forum.rokid.com/index 灵珠平台简介 Rokid 自研 AI 开发平台,基于多模态大模型与轻量化架构,打造零门槛、全栈化 AI 开发体系。平台提供可视化编排、预置能力组件,支持原型到云端、端侧一站式敏捷部署,并深度适配 Rokid Glasses 智能眼镜,通过专属硬件接口与低功耗优化,实现 AI 应用高效端侧落地,助力开发者快速打造视觉识别、语音交互等穿戴式 AI 应用,拓展 AI + 物理世界的交互边界可视化编排工具,拖拽式快速搭建应用预置丰富能力组件库,涵盖对话引擎、视觉识别等核心模块支持从原型设计到云端、端侧的一站式敏捷部署提供设备专属适配接口,实现硬件深度协同搭载低功耗运行优化方案,

# OpenClaw QQ 机器人接入完整指南

作者: 星期五助手 创建时间: 2026-03-05 适用版本: OpenClaw 2026.2.26+ 📖 目录 1. 项目概述 2. 环境准备 3. 安装 NapCat QQ 机器人 4. 配置 OpenClaw QQ 插件 5. 网络配置(关键) 6. 测试与验证 7. 常见问题 项目概述 本指南介绍如何将 OpenClaw 接入 QQ,实现通过 QQ 与 OpenClaw 智能助手对话。 架构说明 ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │ QQ 用户 │ ──→ │ NapCat │ ──→ │ OpenClaw │ │ (发消息) │ │ (QQ 机器人) │ │ (星期五)