Microsoft Bot Framework通过request.user识别用户仅返回最新用户信息问题
问题解决方案
问题根源
你使用global全局变量存储用户和问候语信息,Node.js服务的全局变量是所有请求共享的,并发请求时后到达的请求会直接覆盖之前的变量值,所以多个用户同时访问时都会拿到最后一个用户的信息。另外你初始化UserState时存在错误,传入的是MemoryStorage类而非实例,会导致用户状态存储功能完全失效。
修复步骤
1. 修复UserState初始化错误
修改index.js中的UserState初始化代码,传入已经实例化的memoryStorage对象:
// 错误写法 // const userState = new UserState(MemoryStorage); // 正确写法 const userState = new UserState(memoryStorage);
2. 生成Direct Line Token时绑定用户信息
不要用全局变量传递用户参数,调用Direct Line生成Token接口时,将用户信息绑定到当前Token对应的用户身份上,修改/direct_line/mybottoken接口的请求逻辑:
server.post('/direct_line/mybottoken', async function(req, res) { const userName = req.body.userName; const botGreet = req.body.botGreet; const result = await fetch('https://directline.botframework.com/tokens/generate', { method: 'POST', headers: { Authorization: 'Bearer ' + process.env.DirectLineSecret, 'Content-Type': 'application/json' }, // 将用户信息绑定到该Token,后续会话可直接读取 body: JSON.stringify({ user: { id: userName, name: userName, greet: botGreet } }) }); const token = await result.json(); res.send(token); });
3. 从会话上下文读取当前用户信息
修改mybot.js中的成员加入事件逻辑,直接从当前会话的上下文中读取对应用户的信息,无需访问全局变量:
this.onMembersAdded(async (context, next) => { const { channelId, membersAdded, from } = context.activity; if (channelId === 'directline' || channelId === 'webchat') { for (let member of membersAdded) { if (member.id === context.activity.recipient.id) { // 读取当前会话绑定的用户信息,不同用户之间完全隔离 const currentUser = from.name; const currentGreet = from.greet; if (currentUser == 'Guest'){ await context.sendActivity("Hi there guest !"); }else{ await context.sendActivity(currentGreet); const reply = MessageFactory.suggestedActions(['😀', '😐', '😕']); await context.sendActivity(reply); } } } } await next(); });
额外注意事项
- 若需要长期存储用户偏好、历史会话等信息,可以将用户数据存入
UserState,每个用户的存储内容完全隔离,不会出现串数据的问题。 - 生产环境不要使用
MemoryStorage,服务重启或多实例部署时会出现数据丢失、不共享的问题,建议替换为CosmosDB、BlobStorage等持久化存储方案。
内容的提问来源于stack exchange,提问作者jsanchezs
相关产品推荐
相关产品推荐

