起因
nacos的管理员账号nacos,密码abcdeF@2023
因为使用的是弱密码,所以需要更新密码,密码更新后是.XYDGe1m3aBm09#sm
现象
1. springboot程序启动脚本中也修改成最新密码,但是启动后日志一直打印报错:
c.a.n.client.config.impl.ClientWorker : [fixed-110.120.119.11_8081] [check-update] get changed dataId error, code: 403
2. 在本地测试时发现把密码设置成.XYDGe1m3aBm09#sm类似的比如abcdef#dd也会报错,但是改成abcdeF@2023这种密码就不会报错。
分析
1. 报错表示该账号没有权限,因为管理员账号的权限最大并且只是修改的密码所以不可能是nacos服务端出的问题,那就有可能是nacos客户端的问题。
2. 通过日志关键字在nacos客户端源码定位到报错的方法:com.alibaba.nacos.client.config.impl.ClientWorker类下的checkUpdateConfigStr方法。
这是一个“监听配置”的方法,如果nacos配置中心的配置变更,则通过接口“/nacos/v1/cs/configs/listener”请求nacos服务端获取配置的最新值,动态刷新本地缓存。
3. 通过打断点查看客户端拼接请求地址是“http://110.120.119.11:8081/nacos/v1/cs/configs/listener?username=nacos&password=.XYDGe1m3aBm09#sm”
到这里发现客户端传的账号密码都对的,那为什么服务端还是说账号nacos没权限?为什么只有这个接口报错,没看见其他请求服务端的接口有异常?
4. 为了搞清这个问题我用抓包工具进行抓包分析,之后发现其他正常的请求,比如请求地址是“http://110.120.119.11:8081/nacos/v1/ns/instance/list?app=weixin&healthyOnly=false&password=.XYDGe1m3aBm09%23sm&namespaceId=public&clientIP=110.120.119.11&serviceName=DEFAULT_GROUP%40%40blade-log&udpPort=66666&encoding=UTF-8&username=nacos”
接口“/nacos/v1/cs/configs/listener”请求地址是“http://110.120.119.11:8081/nacos/v1/cs/configs/listener?username=nacos&password=.XYDGe1m3aBm09”
对比后发现,接口“/nacos/v1/cs/configs/listener”接口的密码参数少了几个字符而且是从#特殊字符也就是%23开始少的。
解决方案
因为有几十个服务都在用nacos账号并且刚刚改了一遍密码所以不能再改了。这些服务程序与nacos服务端之间还有一层nginx做代理,所以可以在nginx中把这个接口丢失的字符拼上。
nginx修改配置如下:
server {
listen 8081;
server_name 110.120.119.11;
location / {
set $end_str "%23sm"; #声明变量$end_str
if ( $request_uri = "/nacos/v1/cs/configs/listener?username=nacos&password=.XYDGe1m3aBm09" ) { #判断请求uri是否是要拼接的请求地址
rewrite ^(.*)$ $1?$args$end_str break; #使用rewrite重定向指令拼接丢失的字符
}
proxy_pass http://nacos-cluster;
}
}
完成上述修改后重新加载nginx配置,程序就不再报错了。