Web Hosting 中 AV.User.current() 串号

#3054 /
xingrz
/ 云代码 @ 3 years ago 完成
1. 如果 avos-express-cookie-session 的 fetchUser 设置为 true,经常会发生 AV.User.current() 得到的用户经常是不完整的。
2. 如果自己在 app.get('/', function (req, res) { ... }) 里面 AV.User.current().fetch().then( ... ),经常会获取到别的用户,串号了。

请问如何解决?

xingrz @ 3 years ago

如果我没理解错你们 SDK 源码,你们竟然是从 avos-express-cookie-session 中间件里解析 Cookie 取出 AV.User 实例写到全局,然后 AV.User.current() 又从全局读取。不串号才怪……

xingrz @ 3 years ago

```js
app.use(function (req, res, next) {
  if (!req._avos_session || !req._avos_session._uid) {
    return next()
  }

  var user = new AV.User()
  user.id = req._avos_session._uid
  user._sessionToken = req._avos_session._sessionToken
  console.log(user)
  user.fetch().then(function () {
    req.user = user
    //console.log(user)
    next()
  }, next)
})
```

暂时 Hack 解决了。。。诶,坑

[LeanCloud] xzhuang.leancloud @ 3 years ago

这个问题是已知的,你是本地测试遇到串号还是线上?线上应该不会才对。

我们准备推一个新的 middleware,做法跟你类似,就是将 user 放到 request 里,而非全局变量。全局变量是不安全的做法。

[LeanCloud] sdjcw @ 3 years ago

你好:
感谢你华丽丽的指出了我们的问题,我们也惭愧的解释下:
其实我们很早以前就发现了这个问题,但是因为一些原因暂时没改。

这个问题有点复杂,因为 JS-SDK 当初设计是希望既能在 client 端用,也能在 server 端用。但前者 User 放在全局变量是合理的,后者是扯淡的。所以我们考虑服务端把 User 放在 req 上(其实你从我们文档也能看到,我们是倾向于从 req 中获取 User 的)。
但是用户如果在云代码的方法里做了「登入」或者「登出」的动作,然后再调用存储等 api,我们是否在其登入登出的时候修改 currentUser,使其在调用 api 的时候能从 currentUser 上获取到用户相关的信息,从而进行 ACL 认证?

所以进入一个两难的问题:服务端设置 currentUser 会串号;不设置会使得调用 REST API 无法正确感知到用户信息。

有些解决办法:
比如让大家在云代码里调用 REST API 前手动的 setCurrentUser(代码一定很丑陋很扯淡)
比如 JS-SDK 在调用 REST API 的时候,大家制定一个 user 对象(JS-SDK 一定涉及到大量的修改,也是很扯淡的事)

唉~ 所以这个问题就一直悬而未决。。。。。(当然。。。我承认之前也没有足够重视这个问题,想当然的认为“大家的请求量不太大的情况下没事。。。”)

So~ 既然你华丽丽的指出了我们的问题,所以我们决定把它重新提上日程,并尽快的想办法解决掉!我们初步打算使用 domain 来解决:http://nodejs.org/api/domain.html
当然,如果你有更好的建议,我们非常感谢!!

xingrz @ 3 years ago

是线上,华丽丽地串号了。。。

原本用户没数据的时候我还以为只 fetchUser 没起作用,后来才发现是直接串号掉。表现就是往往 POST 登录成功后的那个页面是正常的,然后那个页面 AJAX 请求的就完蛋了。。。

你的解决办法,手动 setCurrentUser 肯定是不行的,因为这样还是把用户写到了全局里。虽说 JS 是单线程,但是一旦代码里包了一层回调,很可能下一个 tick 里就会被覆盖掉。

我觉得所有需要调用 REST API 的操作都需要指定 user(否则当成未登录处理),这是唯一可以彻底解决办法的途径。

这个问题尽早解决最好,不然真的没法用。我的应用发现频繁串号时才200人的规模。。。

[LeanCloud] sdjcw @ 3 years ago

你好,解决串号的功能开发基本完成,我们开始进入测试阶段,不出意料过几天就能用了。

[LeanCloud] sdjcw @ 3 years ago

你好,我们解决串号问题的功能已经 beta 测试,如果你愿意,我们非常欢迎你的应用参与 beta 测试~!
参与 beta 测试只需要提供 appId,并回复确认即可。我们会在后台将你的应用加入到 beta 列表。
这次 bugfix 不需要应用修改任何代码。只需要我们加入到 beta 列表后,重新部署应用即可生效。