链接(二维码)分享需求
- 功能模块添加分享链接(二维码)功能,通过分享出去的链接,可查看功能模块的详情。
- 分享出去的链接在1天/3天/7天/30天/永不过期,打开过期的链接,弹出提示页面链接已过期。
- 3某些模块分享的链接只能由系统内的指定用户打开,在其他系统外或者非指定的用户打开提示无权限。
- 支持
Android/Ios/Web端分享,在Android/Ios端内扫描二维码直接跳转至相应功能模块
程序设计方案
数据库脚本
1 | sql复制代码CREATE TABLE `url_share` ( |
接口新开Or复用已有接口
事先与客户端约定所有用于分享链接(二维码)的接口request uri前添加/share前缀作为分享接口的标识
1.新增/share/xxx的接口
比如现有业务依赖/doBiz接口,需要实现分享功能
1 | java复制代码@PostMapping("/doBiz") |
新增一个用于分享的接口,定义为/share/doBiz,然后复用service的方法
1 | java复制代码@PostMapping("/share/doBiz") |
每有一个新模块需要分享功能,在控制层controller要增加一个或者多个/share/xxx的接口,造成代码重复。试想在不同的版本迭代过程中,都会存在模块添加分享功能的需求,到时候再去增加一个或者多个/share/xxx的接口,这是很难接受的。
2.篡改请求复用已有接口
Servlet的Filter或者Spring Cloud的ZuulFilter允许我们在收到请求真正转发给ServerletDispatcher之前修改HttpServerletRequest的request uri和request param,下面是一个通过Spring Cloud的ZuulFilter篡改请求的例子。
2.1与前端约定所有分享页面调用业务接口的格式为:
1 | java复制代码Get(Post) /share/doBiz... |
2.2配置可用于通过/share/xxx访问的接口uri
如果将所有接口都允许通过/share/xxx的形式暴露出去,这是非常严重的系统漏洞,对于业务数据敏感的业务可能会带来无法挽回的损失,我们可以通过配置文件给每个模块配置允许通过/share/xxx访问的接口,这样在每次需要给新模块添加分享功能时,仅仅需要添加配置文件,对于不符合配置模块请求uri的接口,跳过篡改请求参数(地址)的Filter继续执即可。
配置文件urshare.json
1 | json复制代码[ |
- htmlUrl:生成的分享的链接地址前缀,最终生成的分享链接形式一般为http://172.16.1.133:9529/#/share?shareToken=xxx
- reqUrls:分享链接的页面需要请求的后台uri地址
- module:分享模块
2.3匹配uri是否符合规则的方法
1 | java复制代码public static boolean pathMatchPattern(String path, List<String> patterns) { |
篡改HttpServletRequest请求和校验/share/doBiz请求网关ZuulFilter
1 | java复制代码@Component |
- 由于部分接口访问需要获取用户信息,先通过
ApplicationRunner.run初始化分享Cookie(Token)的Session数据 shouldFilter方法用于判断/share/doBiz请求,是否允许经过UrlShareFilter篡改请求uri和参数,判断逻辑:匹配请求是否符合urlshare.json配置的reqUrls其中的一条uri规则,是的话就需要通过run方法篡改请求。run方法根据shareToken查找此次分享的参数信息,如链接时效性 有效性 授权人并校验,其次篡改RequestUri去除/share前缀和requestParam,添加用于分享用的Cookie(Token)信息- 注意
UrlShareFilter的优先级应该配置最高优先级
生成二维码
使用hutool工具包的QrCodeUtil类创建二维码并返回给客户端
1 | java复制代码 @PostMapping(value = "/shareUrlQrcode", produces = "application/octet-stream;charset=UTF-8") |
总结
生成二维码最好不要将过期时间/授权用户信息直接加密放到requestParam参数传递,因为参数大小的不确定性将会导致二维码非常密集,相机在扫描密集二维码的效果会变得很差很差。
通过shareToken,后端交由UrlShareFilter根据shareToken获取校验过期时间/授权用户;前端可以通过shareToken参数调用接口得到分享页面所需的参数信息。并且二维码链接的长度确定,二维码的扫描性能得到了保证。
本文转载自: 掘金