1***@qq.com
1***@qq.com
  • 发布:2025-07-30 14:57
  • 更新:2025-07-31 10:50
  • 阅读:280

【报Bug】uni-id登陆成功后获取uni_id_token,任意修改uni_id_token居然还可以获取数据

分类:uniCloud

产品分类: uniCloud/App

操作步骤:

同上

预期结果:

同上

实际结果:

同上

bug描述:

我不知道是不是因为我是开发环境才有这个问题,我感觉不应该啊,是不是我云端没有进行uni_id_token的校验?不然这真的太吓人了

2025-07-30 14:57 负责人:无 分享
已邀请:

最佳回复

DCloud_UNI_yuhe

DCloud_UNI_yuhe

可能是这个接口本身没有校验?你可以直接测试uniID.checkToken试一下

  • 1***@qq.com (作者)

    uni-id是需要手动在云端调用uniID.checkToken进行校验的吗?我以为他是自动校验的

    2025-07-30 17:26

  • 1***@qq.com (作者)

    1.我发现就我现在测试环境,每一次拿到的uni-id-token都是相同的,就是不会变化,我怀疑他是不是一个测试token,前端只是判断有没有token和过没过期,云端实际上不会生成新的token和校验token

    2.我看文档说,在前端使用uniCloud的sdk进行调用jql调用云函数和云对象,会自动携带token,我也确实在请求参数里看到token自动携带了,问题其实就出在云端为什么没有生成新的token和进行校验token,是需要手动进行校验吗?还是说这是bug?

    2025-07-30 17:30

  • DCloud_UNI_yuhe

    回复 1***@qq.com: 你说的自动校验是怎么自动校验?是请求的时候就校验?不是这样的

    2025-07-30 17:35

  • DCloud_UNI_yuhe

    回复 1***@qq.com: 没有理解你说的,云端请求会生成新的token,这个不是每次请求都生成新的

    2025-07-30 17:40

  • 用户2860235

    回复 DCloud_UNI_yuhe: 哎呀,我对jwt的理解不深,J wt的第一个点前面部分是一直不会变化的,我以为它每次获得新token这一部分是会变化的,然后我看他第一部分一直没变化,导致我以为整个token没变化,我现在已经发现了更新token,jwt的第二个部分会变化。

    2025-07-30 18:17

  • 用户2860235

    回复 DCloud_UNI_yuhe: 嗯,但现在其实我就是有一个问题,就是比如你前端token,你给他设置成一个10秒的过期时间,那你调用jql,他不是会去检校验你那个token吗?按道理你现在的uni-id-token比如过期了,jQL不应该就调用失败吗?我前端还能拿到数据,我就觉得很奇怪,我其实是这个意思,然后刚才那个token不变,是我理解错了。

    2025-07-30 18:19

  • 用户2860235

    回复 DCloud_UNI_yuhe: 我的意思是为什么云端没有校验token失败,然后给我前端返回一个token校验失败的信息,而是让我前端正常的拿到了jql调用到的数据?

    2025-07-30 18:20

  • DCloud_UNI_yuhe

    回复 用户2860235: 我觉得应该是你没有走到校验的地方,你详细说一下,你是如何调用的

    2025-07-30 18:20

  • 用户2860235

    回复 DCloud_UNI_yuhe: 就我之前完全没有引入uni-id,我有一个页面是前端使用unicloud直接调用数据库做的demo,数据库表的schema.json没有进行任何限制,(我现在回过神来,我在想是不是应该在这一个表结构定义里面去限制如果token过期就不返回数据?)然后我现在引入了uni-id,嗯,就之前是前端使用unicloud调用数据库,我可以看到请求已经附带了uni-id-token,并且本地存储也存储了这个uni-id-token,但是uni-id-token过期后,感觉数据库就是没有任何校验uni-id-token,直接就把数据给我了

    2025-07-30 18:26

  • DCloud_UNI_yuhe

    回复 用户2860235: 你是写在云对象或者云函数的方式请求,还是直接在前端写请求数据库?

    2025-07-30 18:29

  • 用户2860235

    回复 DCloud_UNI_yuhe: 直接在前端调用unicloud.database请求的数据库

    2025-07-30 18:29

  • DCloud_UNI_yuhe

    回复 用户2860235: 如果你的请求数据库写在云对象或者云函数中,需要设置 clientInfo 的 uniIdToken

    2025-07-30 18:30

  • DCloud_UNI_yuhe

    回复 用户2860235: 需要使用 uniCloud.databaseForJQL() 而不是 uniCloud.database()

    2025-07-30 18:32

  • 用户2860235

    回复 DCloud_UNI_yuhe: 还有这一层关系的啊,神医啊,这两个API有什么区别吗?就我发现在前端写的时候,他们俩嗯比如一些联表查询,他们俩可以用的那些API几乎都是一模一样的,只有在云端的时候才会有比较大的区别,在前端我一直默认这两个东西是一样的,那现在突然发现了,他又有区别了,可以解释一下嘛。

    2025-07-30 18:35

  • DCloud_UNI_yuhe

    回复 用户2860235: 简单来说就是增强了jql 的能力,扩展了一些功能,具体可以见文档:https://doc.dcloud.net.cn/uniCloud/clientdb.html#jssdk

    2025-07-30 18:37

  • 用户2860235

    回复 DCloud_UNI_yuhe: 趁这个机会再问一下。

    2025-07-30 18:43

用户2860235

用户2860235

就是数据库的数据都正常返回了。我看那个请求里的信息。也没有说哪个是异常的,哎,他是怎么知道token过期了,然后数据加载失败了呢。

  • DCloud_UNI_yuhe

    token 过期是有时间设置的,每次校验也是会看时间的 tokenExpired

    2025-07-30 18:47

  • 用户2860235

    回复 DCloud_UNI_yuhe: 我发现他为什么会报这个错误呢?因为unicloud.database和unicloud.databaseForJql他俩的返回值是不同的。我一开始使用的是第一个,就是第一个它的返回值是一个对象在包对象,然后第二个的返回值是直接一个对象里面就是数据了,能懂吗?所以我才会出现那么一个报错,也就是说什么意思呢?就是说这两个东西其实都把数据返回来了,只是数据格式不同

    2025-07-30 19:58

  • 用户2860235

    回复 DCloud_UNI_yuhe: 然后我自己做了捕获错误,才会在浏览器上显示出这个错误。也就是说token过期。这两个接口其实都把数据返回给了前端,云端并没有做任何校验,前端没有任何报错。

    2025-07-30 19:59

  • 用户2860235

    回复 DCloud_UNI_yuhe: 而且我测试了database和databaseForJql的表现是一样的,我把uni-id-token都从本地存储删掉了,第一次地址栏访问页面依旧没有触发拦截,得刷新一下才触发拦截

    2025-07-30 20:05

  • 用户2860235

    回复 DCloud_UNI_yuhe: 但这样会有一个bug,比如我如果不刷新页面,我现在在页面内执行任何操作,比如下拉加载更多数据,明明uni-id-token过期了,或者没有uni-id-token,请求都不会有任何问题,除非你刷新页面

    2025-07-30 20:09

  • 用户2860235

    回复 DCloud_UNI_yuhe: 不过思考了一下感觉好像也对,uniIdRouter的效果应该就和路由守卫一样,只拦用户访问权限页面,如果你本身已经在权限页面里面了,那就不是uniIdRouter该考虑的事情

    2025-07-30 20:14

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 我给你描述一下情况,一开始登录是在“http://localhost:5173/#/”页面,然后“http://localhost:5173/#/pages/demo1/list”是权限页面token过期会被拦截,我每次在地址栏从“http://localhost:5173/#/”页面,输入“http://localhost:5173/#/pages/demo1/list”第一次都没触发拦截,而是要刷新一下才会触发拦截,

    而且我测试过如果直接把“http://localhost:5173/#/”设置为权限页面,第一次上去就会触发拦截,太神奇了

    2025-07-30 20:17

  • DCloud_UNI_yuhe

    回复 用户2860235: 这个格式的问题,在文档中有说明的

    2025-07-31 09:26

1***@qq.com

1***@qq.com (作者)

现在最后就是两个问题,第一个问题是:
一开始登录是在“http://localhost:5173/#/”页面,然后“http://localhost:5173/#/pages/demo1/list”是权限页面token过期会被拦截,我每次在地址栏从“http://localhost:5173/#/”页面,输入“http://localhost:5173/#/pages/demo1/list”第一次都没触发拦截,而是要刷新一下才会触发拦截,

而且我测试过如果直接把“http://localhost:5173/#/”设置为权限页面,第一次上去就会触发拦截。

第二个问题是,前端使用 database 和 databaseForJql 会携带 uni-id-token,但是

如果 uni-id-token 被我修改为任意字符,云端数据库没有进行校验,依旧会把数据返回回来,这是异常的,uni-id-token 都错了不应该返回数据(也就是说 uni-id-token 错误的情况云端是完全没有校验的),

如果是 uni-id-token 过期,此时前端会触发拦截,调用数据库的请求都发不出去,这是正常的,

如果直接本地存储清空 uni-id-token,也就是前端完全没有 uni-id-token,如果不刷新页面,在当前页面进行云端数据库调用,调用数据库的请求完全没有携带 uni-id-token,也会把数据返回回来,这是异常的,如果刷新页面,此时前端会触发拦截,调用数据库的请求都发不出去,这是正常的

(感觉和我猜的一样,云端完全没有对 uni-id-token 进行校验,对 uni-id-token 的校验感觉都在前端,包括 token 过期,前端不存在 token,这两种情况看起来是在前端进行校验的,token 错误在云端没有进行校验,导致出现异常)

1***@qq.com

1***@qq.com (作者)

对于我的第一个问题,其实我已经有了猜测,从首页手动在地址栏输入子路径时,uniIdRouter 没有检测到,也就是说没有监听 hashChange事件,他压根就没发现我路径切换了,我可以这么理解吗?那这一部分大概率就是路由守卫的逻辑有问题,而且很可能是没有监听 hashChange事件,也可能是监听了 hashChange事件,捕获了路径的切换,但是没有执行路由守卫的逻辑?

  • DCloud_UNI_yuhe

    看你第一个问题,你说的触发拦截,你先得确定是哪个位置触发的拦截,看起来是在特定的生命周期中,没有执行拦截逻辑。第一次没触发拦截,那么返回的信息是什么呢?

    2025-07-31 09:33

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 就是通过 uni.navigateTo 触发的路由切换,进入新的页面,如果这个页面在 uniIdRouter 配置了拦截,会触发前端校验,如果是通过地址栏输入对应路由,进入的页面,这个页面在 uniIdRouter 配置了,不会触发前端拦截,只会发请求触发云端校验,现在的问题就是这样

    2025-07-31 09:50

  • DCloud_UNI_yuhe

    回复 1***@qq.com: 方便的话提供一下一个测试项目吧,可以打包成一个zip发到评论中,我给你看一下

    2025-07-31 09:52

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 也就是说,我在地址栏输入的路由切换,uniIdRouter 好像是没有发现,又或者说 uniIdRouter 发现了但是没有执行前端的 token 是否为空,是否过期的校验,而是直接就请求云端了

    2025-07-31 09:52

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 行

    2025-07-31 09:53

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 好了

    2025-07-31 10:04

1***@qq.com

1***@qq.com (作者)

对于我的第二个问题,也已经有答案了,为什么之前前端调用数据库没校验原因就在 schema 表结构这里,当我配置:

  "permission": {  
    "read": "auth.uid != null",  
    "create": true,  
    "update": true,  
    "delete": true  
  },

错误的 token 马上在云端被校验,并且数据库数据完全没有返回,前端直接报错,这就对了,问题就在于 schema 表结构定义权限!现在我这边测试一点 bug 也没有了,甚至我之前说的第一个问题,也是一点 bug 没有了,因为我没有配置 schema 权限之前,云端不校验,前端怎么请求数据库都不可能会出问题的,不管前端是否携带 token,整个逻辑跑通了,前端调用数据库的逻辑是:

前端本地先校验有没有 token,然后判断是否过期,然后上传到云端,云端根据 schema 表结构定义,进行云端 token 判断,如果没有定义 schema 那就不进行云端判断,判断成功前端拿到数据库数据,看似很完美对吧,我发现了一个致命 bug!

我在 schema 表结构定义了对应权限,我的请求还是发送出去了,而且是在云端校验过后发现我前端没有携带 token 到云端,才给我报的错,也就是说我前端的 token 被我清空了,前端没有先进行一遍是否有 token 的校验,直接就把请求发出去了,然后错误是在云端校验的时候整出来的,这不对吧?我测试了好几次,前端没有 token 请求依旧发出去了

1***@qq.com

1***@qq.com (作者)

不对啊,我本来以为没有前端校验有无 token 和是否过期,但是我发现,前端校验通过路由点击跳转的会触发,

我拦截了“pages/demo1/.*”,直接在地址栏输入“pages/demo1/list”回车没有触发前端校验,直接调用云端校验,也就是说uniIdRouter压根没发现我地址栏的输入,可能是没有监听 hashChange事件,

然后通过点击切换路由到“pges/demo/detail”,此时就触发了前端校验,不仅在前端 token 为空又或者前端 token 过期,都可以准确的拦截到登录页,这非常对啊,

也就是说现在云端校验的问题已经解决了,非常好,没问题,问题在于前端校验,在于地址栏切换路由没有触发前端校验

1***@qq.com

1***@qq.com (作者)

就你试着启动项目,现在 uniIdRouter 是配置拦截了"pages/demo1/.*"页面,

你试着从首页访问然后在地址栏输入“pages/demo1/list”就可以复现我这边的问题,当然要先把本地的 token 清掉,或者修改本地的 token 时间改为过期,然后你会发现前端没有进行校验空 token 和 token 过期,是把请求发送出去,在云端校验的空 token 和 token 失效的问题,

然后你进行登录,登录成功后,会在“pages/demo1/list”页面,此时你再次尝试把本地的 token 清掉,或者修改本地的 token 时间改为过期,点击任意一张卡片,此时会通过 uni.navigateTo 触发路由跳转到“pages/demo1/detail”,你会发现进行了前端校验,直接就拦截到了登录页,请求没有发出去

  • DCloud_UNI_yuhe

    你是不是没有发出来项目?

    2025-07-31 10:11

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 奇怪,明明上传附件,怎么好像没发出去

    2025-07-31 10:13

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 我说怎么附件我看不见,我还以为他这么神奇,附件上传就是自己看不见的

    2025-07-31 10:14

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 我知道问题在哪了,我改一下,文件大小超过上限被拦截了,我把uni-module里的包删一下

    2025-07-31 10:17

  • DCloud_UNI_yuhe

    回复 1***@qq.com: 还是没有上传成功看起来,你把产物中的unpackage也删除,只保留源码即可

    2025-07-31 10:20

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 好了

    2025-07-31 10:24

1***@qq.com

1***@qq.com (作者)

上传附件

1***@qq.com

1***@qq.com (作者)

我把 node_modules 和 unpackage 都删掉了,demo 里用到了 dayjs 再使用 pnpm i 安装一下就行

DCloud_UNI_yuhe

DCloud_UNI_yuhe

我这里尝试运行了你发的代码,但是你看这是你期望的效果吗?

  • 1***@qq.com (作者)

    对的,前端没有 token 或者 token 过期,没有先进行前端校验就直接发送请求到云端进行的云端校验,是不是应该先走一遍前端校验呢

    2025-07-31 10:54

  • DCloud_UNI_yuhe

    回复 1***@qq.com: 是设计的应该是直接请求的,但是你想不校验,看起来你这个需求,不使用 uniidrouter 就不会走校验的呢

    2025-07-31 10:56

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 你可以尝试就是登录成功后,去到 “pages/demo1/list” 页面,点击任意一张卡片,此时通过 uni.navigateTo 触发路由跳转到“pages/demo1/detail”,你会发现进行了前端校验,直接就拦截到了登录页,请求没有发出去

    2025-07-31 10:59

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 然后你会发现其实是有前端校验的,只是在地址栏输入地址触发不了前端校验

    2025-07-31 11:00

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 对了,得先把 token 删掉或者修改 token 的过期时间让 token 过期

    2025-07-31 11:02

  • DCloud_UNI_yuhe

    回复 1***@qq.com: 我看了下,这个是已知问题,为了适配其它平台,暂时只能这样,无法修复

    2025-07-31 11:27

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 哭死o(╥﹏╥)o

    2025-07-31 11:56

  • 1***@qq.com (作者)

    回复 DCloud_UNI_yuhe: 不能在路由的逻辑多加一个如果是 web 端监听浏览器地址栏的 HashChange 事件吗,这样子我在地址栏的修改也就可以被捕获到了...

    2025-07-31 15:14

要回复问题请先登录注册