XX系统无法对接,如何实现文书上传?- 通过RPA爬取数据并破解登录模拟接口实现文书回传

340 阅读8分钟

概述

本文介绍了一个客户因为无法协调对接第三方系统而导致的文书无法上传第三方系统的问题,并给出了一种通过模拟接口并对接第三方登录的解决方案。文章将详细描述解决方案和验证过程,并提供一些技术细节和注意点。

业务背景

我们为某客户做了一个文书服务,辅助客户去制作文书,但是制作文书需要的业务数据在第三方系统中,而且文书还需要上传至第三方系统。这家公司的一贯做法是谁来也不对接,爱咋咋的。我就受不了他这么嚣张,不就是不对接嘛,我就没有别的办法了嘛。项目组讨论,是时候RPA搞他们一顿了。

image.png

生成文书需要的数据已经通过RPA爬取到了,问题是生成的文书如何上传至XX系统?

考虑到通过RPA回传文书的时效性不高,数据流过长,并且依赖RPA,不方便维护,所以定为模拟XX系统的接口进行上传文书;XX系统不是公司所属系统,不能做对接,所以有以下难点:

  • 调用XX系统接口,前提是要解决登录的问题
  • 调用接口回传文书需要在XX系统中找到可用的接口
  • 没有测试环境来测试程序,后期需要现场调试

验证过程

  • 回传方案确认

    1. 在XX系统上找到了文书上传功能,并记录了上传需要的接口和逻辑;

      • 使用账号密码调登陆接口,获取cookie
      • 携带cookie文件引入,上传文件到服务器,返回的html页面中又文件名称,存储路径和类型信息
      • 携带cookie,和解析到的参数调用保存接口
    2. postMan 调试接口,并成功将文件上传到指定位置;

    3. 编码验证,通过启jar的方式在一个可远程地区的xx系统用postman上传文件,通过程序回传文件;

      过程中遇到的问题:在登陆成功后,带着cookie去调引入文件的接口时经常会失败,返回的html页面中文件信息为空?

      解决过程:因为看不到XX系统的日志,只有比较上传成功和失败时调用接口的区别,对比了入参信息发现没什么不同,又对比了header中的信息也没发现不同;而后又使用postman去模拟接口上传,发现也是一样的情况,一度怀疑是XX系统是做了什么限制;

      ​ 最后,还是回到起点,又去点了下系统中的上传操作看能发现什么?然后发现每次引入文件的接口调用的端口有时候不一致,似乎发现了什么,再一看登陆时返回的cookie信息中拼接又4位数的端口,并且后面的文件上传,文件信息保存都是这个端口;

      ​ 分析后推测,XX系统应该是部了三个节点,登陆返回的cookie信息指定了下次访问的节点;

现场调试

​ 现场环境联调有两个问题,一是外网电脑不能连内网环境,没法直接联调XX系统,只能通过替换编译后的class文件来验证,实际降低了调试效率;二是XX系统的登录问题,发现现场XX系统没有使用系统本身的登录,而是用了第三方公司的登录,一个用户一个key,插在电脑上弹窗输入密码后,进入系统时自动登录;

​ 再次确认方案,需要确认第三方登录能否实现?后续的文件上传接口和文件信息保存接口是否能用?如果存在风险,只能通过对接对接RPA的登录获取cookie,或者完全通过RPA的方式回传文书,但这两都不是最佳方案,都有时间上的延迟等问题;

  • 登录确认:

    1. 原有的XX系统的登录是否可用?尝试确认后,不能

    2. 第三方登录是否用有对接文档?咨询现场后,没有

    3. 第三方登录除了插key的方式登录,是否还有其他的登录方式?

      除了插key的方式外,另外在跳转第三方sso-sever登录界面后,通过修改dom元素显示了页面隐藏的口令登录方式,需要输入用户名,密码,验证码;

  • 文件上传确认:

    通过上述用户名,密码,验证码的方式登录了系统获取到cookie,再通过原来的两个接口通过postman验证了原有接口可用。

    所以决定还是直接对接XX系统,对接第三方的登录,实现文书回传到XX系统的卷宗目录;

过程中遇到的问题

重新实现登录,获取cookie,过程要比原有系统的登录要复杂

  1. 跳转第三方登录页面,获取第三方cookie

  2. 请求验证码接口,获取验证码图片

    • 引入tess4j ocr识别插件,识别验证码
  3. 携带1返回的cookie,用户名,密码,验证码调用第三方登录接口

  4. 从第三方登录接口返回的header信息中取到location信息(XX系统的路径),携带3返回的cookie访问此路径获取XX系统的cookie

遇到解决的问题

问题1: 验证码的ocr识别问题?一开始引入tess4j,在服务器运行调用时会发生编译错误,最后还是在linux服务器安装了tess4j插件才解决。

问题2:发现识别出来的验证码的准确性不高,经常会多一些空格,符号什么的?然后通过多次获取验证码的方式来提高准确性,但是也增加了登录的访问时长;最后的最后,还是发现可以跳过验证码的验证,也就是修改登录的表单参数-验证方式_eventId

问题3:在用登录后拿到的cookie来调用后续的文件上传接口时,返回的html信息中文件存储信息一直提示上传文件过大,不能超过20M?

再三确认文件只有十几kb,以为这个hutool的http请求的工具类有什么问题,尝试用了httpclient,restTemplate,还从postman导出了java代码用Okhttp方式的请求,设置了请求header中的Content-type的类型都没有效果,最后重写了hutool的HttpRequst类,修改了表单请求对文件流的处理,为文件流设置Content-type为application/octet-stream。

问题4:在频繁操作文件回传时,会有失败的情况,而且在系统重启后的前3.4次可以回传成功,后面大概率是失败的?

查看日志发现,如果回传失败步骤4返回的location中的cookie就是null;查看hutool的HttpRequst源码发现,在创建http连接后,根据url的host会缓存cookie,所以当多次XX步骤4调用XX系统时,携带的cookie可能不是新的;最后重写了HttpRequst,禁用了缓存得到解决。

问题5:基于上述登录出现的各种问题,对回传的登录做了优化,即缓存每个用户登录成功后的cookie信息,每天用定时任务去清除缓存,并提供了手动清除的接口;

问题6:回传到XX系统的文书,下载后打开发现是乱码?

比较了回传前和回传后的文书的字节,发现回传后的文书多了个换行,去掉后就能成功打开;最后去掉了HttpRequst中CONTENT_TYPE_FILE_TEMPLATE属性值后面的误加换行符。

总结

  1. 在计划方案时,一定要验证方案可行性;
  2. 一般情况下对于这种单方面有风险的对接功能的实现,最好多备几套方案;比如我们直接调用XX系统的接口不成,也会通过对接rpa的方式去登录并回传文书;
  3. 前期要了解现场具体环境,不同地区的同一个系统也有不同情况(可远程地区的XX系统是自己的登录,现场却对接了第三方登录),这次就是因为没有提前了解到现场的XX系统其实已经对接了第三方登录,导致没有提前计划这部分工作量,也是到了现场临时做了对接;
  4. 在处理问题时,多使用排除法,排除相同的场景,比较不同的地方
  5. 不能完全信任开源工具类,还是有具体问题具体分析,关注工具的源码实现