nacos-group / r-nacos

Nacos server re-implemented in Rust.
https://r-nacos.github.io/docs/
Apache License 2.0
840 stars 93 forks source link

grpc连接token过期后直接崩坏 #100

Closed Clownsw closed 5 months ago

Clownsw commented 5 months ago

r-nacos: v0.5.10, 服务一直启动着, 突然( 应该是token过期了 ) 出现未知用户。缺少心跳检查成功后对token进行续期

.env

RNACOS_HTTP_WORKERS=4
RNACOS_RAFT_NODE_ID=1
RUST_LOG=info
RNACOS_ENABLE_NO_AUTH_CONSOLE=false
RNACOS_ENABLE_OPEN_API_AUTH=true

1717058884350

Clownsw commented 5 months ago

这会引起大规模的断线

image

Clownsw commented 5 months ago

src/openapi/auth.rs:37

let login_result = LoginResult {
    access_token: Some(token),
    token_ttl: app.sys_config.console_login_timeout as i64,
    global_admin: false,
};

这里返回了token和ttl, 那么过期之后客户端不再携带token, 则会出现上面无法获取用户导致服务直接崩坏的情况

Clownsw commented 5 months ago

如果将设置了 RNACOS_CONSOLE_LOGIN_TIMEOUT=-1, 会发现一直在登录 (超时) , 那么为什么默认的86400超时后不会尝试重新登录获取token?

.env

RNACOS_HTTP_WORKERS=4
RNACOS_RAFT_NODE_ID=1
RUST_LOG=info
RNACOS_ENABLE_NO_AUTH_CONSOLE=false
RNACOS_ENABLE_OPEN_API_AUTH=true
RNACOS_CONSOLE_LOGIN_TIMEOUT=-1

image

heqingpan commented 5 months ago
  1. 开启鉴权后,超时时间不应该配置成-1。后面考虑对这类冲突的配置直接启动报错。

  2. token过期刷新nacos设计上也是要在客户端刷新的(jwt只能客户端刷新才有效)。 你测试的结果看,客户端没有自动刷新?(这个是配置正常的有效期配置下的结果吗?)这个点有点奇怪,需要再确认一下client sdk为什么没有自动刷新token。

heqingpan commented 5 months ago

在服务端明确返回token过期时间,请求明确返回鉴权失败错误码的情况下,客户端没能自动刷新token,那有可能就是客户端的问题。

我理解服务端开启鉴权后,客户端token过期后没刷新token发起的请求被拒绝是一个合理的处理方式。

后面我抽空和nacos做个对比看看是什么情况。

Clownsw commented 5 months ago

后面我抽空和nacos做个对比看看是什么情

我理解上也是客户端应该重新去刷新这个token, 但是没有, 就直接报错 ( 没有去重新登录 )

Clownsw commented 5 months ago
  1. 开启鉴权后,超时时间不应该配置成-1。后面考虑对这类冲突的配置直接启动报错。
  2. token过期刷新nacos设计上也是要在客户端刷新的(jwt只能客户端刷新才有效)。 你测试的结果看,客户端没有自动刷新?(这个是配置正常的有效期配置下的结果吗?)这个点有点奇怪,需要再确认一下client sdk为什么没有自动刷新token。

我明天重复现一下现场

heqingpan commented 5 months ago

我找到原因客户端没有及时刷新的原因了。

获取token的接口涉及两个时间,一个是生成token有效期,一个是返回给客户端的有效期,这两个时间逻辑上应该是一致的。

但目前版本生成token的有效期取的是openapi_login_timeout,然后返回给客户端的有效期取的是 console_login_timeout。当console_login_timeout比openapi_login_timeout大时,服务token过期后客户端认为还没有过期,就不会触发token刷新。

下个版本会解决这个问题。本周末会发一个版本。

Clownsw commented 5 months ago

我找到原因客户端没有及时刷新的原因了。

获取token的接口涉及两个时间,一个是生成token有效期,一个是返回给客户端的有效期,这两个时间逻辑上应该是一致的。

但目前版本生成token的有效期取的是openapi_login_timeout,然后返回给客户端的有效期取的是 console_login_timeout。当console_login_timeout比openapi_login_timeout大时,服务token过期后客户端认为还没有过期,就不会触发token刷新。

下个版本会解决这个问题。本周末会发一个版本。

好的, 老哥