发布版本内置过快速链接跳转到EFAK(即KafkaEagle),前几天某行业局点ISV客户反馈通过EFAK页面删除Topic失败,提示404异常。页面删除Topic需要输入Admin Token,这玩意输入错误的话,应该会提示403(无权限)。再次让客户确认,拍照如图。 Admin Token其实就是个密码,开发者可能认为删除Topic需要特别权限或需要谨慎操作,才进行二次check。微信公众号私信有时效性、过期不可回复,很多朋友私信我没及时看到、未能回复。最近新建钉钉群(44703541),欢迎朋友加入!问题分析
既然不是Admin Token输入错误,而404通常指访问资源URL不存在。经过沟通交流,ISV客户反馈:后台日志未见任何异常信息;Kafka集群确实存在该Topic。这样的话,基本可以排除ISV客户使用问题了,大概率是踩到原生BUG的坑。现场客户反馈之前修改过Admin Token默认值:keadmin改为fsdfds#fdsfs(已虚构,关键是包含#字符)。本地相同版本的开发环境使用包含#字符的Admin Token成功复现404异常。浏览器F12发现删除topic使用的接口竟然是get方法、Admin Token值直接通过url明文传递。那么,问题就一目了然了。如上图所示:使用Admin Token值为admin#123,删除Topic名称为test。访问的请求为get方法,url为http://felixzh:18048/topic/test/admin
http://felixzh:18048/topic/test/admin#123
所以,404异常确实是因为访问资源url不对导致的。但是,对于http url来说,#属于特殊符号,有其特殊作用。#是用来指导浏览器动作的,对服务器端完全无用,代表网页中的位置,其右面的字符,就是该位置的标识符。比如如下url就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。http://www.example.com/index.html#print
针对该问题解决方法不一。通常用法来说,删除资源一般会使用delete方法,待删除的资源通过Body密文传输。但是,这种改动涉及前端代码稍微多点。最终,决定仍然保持使用原有的get方法,只将Admin Token明文传输改为密文传输。efak-web/src/main/webapp/media/js/main/topic/list.js
前端使用JavaScript内置函数btoa对Admin Token值进行加密,改动量小。如图所示:efak-web/src/main/java/org/smartloli/kafka/eagle/web/controller/TopicController.java
后端对应的Controller先使用Java实现的atob方法对前端传输过来的加密Admin Token进行解密,然后再继续之前原有操作。如图所示:Btoa(binary to asci)用于将binary数据用ascii码表示,即Base64编码。
Atob(ascii to binary)用于将ascii码解析成binary数据,即Base64解码。
详细的加密算法原理这里就不再描述,使用Java语言实现的Btoa和Atob,见我的github地址为:https://github.com/felixzh2020/felixzh-learning-java/tree/master/BtoaAndAtob