V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jaylee4869
V2EX  ›  Java

boss 说了一个骚操作。。。

  •  
  •   jaylee4869 · 2019-12-05 21:18:32 +08:00 · 14732 次点击
    这是一个创建于 1817 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前端传不同的类名(比如 com.xxx.UserService ),后端拿到这个名字反射调用它的方法,实现一个 api 动态配置。。。

    75 条回复    2019-12-09 15:39:03 +08:00
    hcymk2
        1
    hcymk2  
       2019-12-05 21:28:44 +08:00
    DWR
    chengyiqun
        2
    chengyiqun  
       2019-12-05 21:54:21 +08:00
    这个不够安全, 应该加点限制, 我们公司有类似的, 通过传入不同的 URL 资源地址, 然后解析后查询配置表, 然后反射 dubbo 调用. 真的有类似的. 完全可以实现.
    注意, 前台只传标识, 类名啥的还是方自己版本的配置表里.
    eason1874
        3
    eason1874  
       2019-12-05 22:01:52 +08:00
    Java 咋样不了解,我接触很多 PHP 程序都有类似操作。每个 API 是一个独立的类文件,类是根据变量名动态加载的,而变量名则是其他地方传入或者前端传入,加一个 API 的时候加一个类文件就可以了,删一个 API 的时候也是删那个类文件或者改名就可以了。
    t123yh
        4
    t123yh  
       2019-12-05 22:02:30 +08:00 via Android
    如果传送了具有危险的命令,怎么办呢
    heyjei
        5
    heyjei  
       2019-12-05 22:04:21 +08:00
    @t123yh 白名单啊
    snw
        6
    snw  
       2019-12-05 22:11:44 +08:00 via Android
    Linux 上那个 Snapcraft 好像也有类似的骚操作,各种包的命令文件都软链指向同一个可执行文件,但 snap 知道你要运行哪个。
    CODEWEA
        7
    CODEWEA  
       2019-12-05 22:12:59 +08:00
    很正常呀,以前的 php 路由不就是这样吗 c=控制器 m=方法
    xupefei
        8
    xupefei  
       2019-12-05 22:14:52 +08:00 via iPhone
    @snw 还有 busybox
    learnshare
        9
    learnshare  
       2019-12-05 22:36:09 +08:00 via Android
    这么写 API 的也见过,处理得当的话,或许没太大区别
    superrichman
        10
    superrichman  
       2019-12-05 22:36:57 +08:00
    这种设计我觉得后面肯定会出安全问题
    ClericPy
        11
    ClericPy  
       2019-12-05 22:47:19 +08:00
    就喜欢看这些骚操作哈哈

    以前用 python 也干过类似的事情, 确实方便, 一个 route 让我接了几十个 utils..... 而且也方便一句 /doc 当场看文档, 至于安全问题, 做了限权和 slots, 问题不太大

    不过后来就不这么折腾了, 看 doc 也用 swagger
    dremy
        12
    dremy  
       2019-12-05 22:49:48 +08:00 via iPhone
    文件系统即路由,没毛病呀
    luozic
        13
    luozic  
       2019-12-05 22:52:32 +08:00 via iPhone
    模型最好统一,这里骚了,别的地方继续 mvc 或者 mvvm,之后维护你就知道啥叫蛋疼了。
    areless
        14
    areless  
       2019-12-05 22:55:09 +08:00
    可以的。加密一下。MySQL 开 ssl,前端直接写 sql 都可以的。node 的 ORM 改造下直接在浏览器端使用,很方便的。
    darkforest8848
        15
    darkforest8848  
       2019-12-05 23:03:58 +08:00
    以前我们的项目就是这么设计的
    Samuelcc
        16
    Samuelcc  
       2019-12-05 23:45:21 +08:00 via Android   ❤️ 1
    这种维护成本是不是有点高,重构火葬场
    Evrins
        17
    Evrins  
       2019-12-06 00:45:38 +08:00 via iPhone
    Play framework 1 就是这样的
    Kaiv2
        18
    Kaiv2  
       2019-12-06 08:35:11 +08:00 via Android
    建议使用 spring MVC
    ershisi
        19
    ershisi  
       2019-12-06 08:51:57 +08:00
    算不上骚操作,只要权限控制没问题就没啥毛病的吧
    fengpan567
        20
    fengpan567  
       2019-12-06 08:53:25 +08:00
    之前做了个定时任务,就是这么搞的
    uxstone
        21
    uxstone  
       2019-12-06 09:09:57 +08:00
    低内聚 高耦合
    boss 说归说,最终出 bug 还是你来加班改,如果甩给后来人不太厚道
    greenlaw110
        22
    greenlaw110  
       2019-12-06 09:11:52 +08:00
    @Evrins Playframework1 哪里是这样, route 配置在后端, 前端不可能传递后端的实现细节的, 这种不是骚操作, 这种是瞎操作
    xuanbg
        23
    xuanbg  
       2019-12-06 09:23:51 +08:00
    后端 API 需要动态配置么?
    前端模块动态加载倒是常规操作,无论是导航数据里面配路由的 web 应用还是配类名的桌面应用都是这个套路。
    vanishcode
        24
    vanishcode  
       2019-12-06 09:25:41 +08:00
    dubbo 那一套,有公司是这么做的,前端+网关都是 ts
    JasonLiHai
        25
    JasonLiHai  
       2019-12-06 09:30:15 +08:00
    这个以前做过
    mskf
        26
    mskf  
       2019-12-06 09:31:57 +08:00
    java RMI?
    keller
        27
    keller  
       2019-12-06 09:42:26 +08:00
    坐下坐下 这是常规操作
    opengps
        28
    opengps  
       2019-12-06 09:46:37 +08:00
    其实挺常见的,只不过传的不一定刚刚好是类名,可能得转一下,比如前端传 user,传 product
    lihongjie0209
        29
    lihongjie0209  
       2019-12-06 10:04:37 +08:00
    @areless #14
    1. 数据库改密码所有客户端都要更新?
    2. 你的数据库连接数 == 你的用户数?
    deweixu
        30
    deweixu  
       2019-12-06 10:09:14 +08:00
    把 bean 放到一个 map 中,前端传 key, 后端取出 bean 调用相关的方法处理
    hoyixi
        31
    hoyixi  
       2019-12-06 10:13:03 +08:00
    传个 binary 对象或者代码,然后再组装调用,是不是更骚?
    yuankui
        32
    yuankui  
       2019-12-06 10:13:08 +08:00
    再怎么也搞个映射吧??

    直接上类名,不担心安全问题?
    yeyuhan
        33
    yeyuhan  
       2019-12-06 10:14:05 +08:00
    直播实现 RCE
    xfriday
        34
    xfriday  
       2019-12-06 10:23:04 +08:00
    rpc 么好了,哪有这么麻烦
    Orenoid
        35
    Orenoid  
       2019-12-06 10:27:05 +08:00
    做好限制,问题不大。但是如果文档不完善,后来维护的可能会一脸懵逼。
    RYAN0UP
        36
    RYAN0UP  
       2019-12-06 10:29:00 +08:00 via iPhone
    我司之前就这么干的。传 target method。
    Tink
        37
    Tink  
       2019-12-06 10:37:37 +08:00 via iPhone
    这个可以的
    th00000
        38
    th00000  
       2019-12-06 10:40:15 +08:00
    可以在前期先把这些对象都创建出来, 根据前端传递的方法, 去配置里直接拿出来调用, 速度会快很多
    tabris17
        39
    tabris17  
       2019-12-06 10:41:52 +08:00
    不怕被注入什么危险代码吗?
    areless
        40
    areless  
       2019-12-06 10:41:59 +08:00 via Android
    @lihongjie0209 mysql 是多用户的,在 mysql 库里添加用户权限咯,有的能写有的只读有的不让读。连接又不是持久的,读完就关,1000 个连接数能跑好多呢。myisam 一个用户生成一个表咯。。。以前 WordPress 多用户版插件是这样搞的。速度又快~
    lihongjie0209
        41
    lihongjie0209  
       2019-12-06 10:51:38 +08:00
    @areless #40
    1. 哪怕读完就关,1000 连接就是 1000 并发, 你的并发和连接数是相同的, 不好扩展。
    2. 一个用户一个表, 如果我的系统有 20 个表用户可以访问, 我有 10000 个用户, 那么我需要 20 * 10000 个表??
    jsq2627
        42
    jsq2627  
       2019-12-06 11:02:57 +08:00
    常规操作 常规操作..
    vinHty
        43
    vinHty  
       2019-12-06 11:29:03 +08:00
    印象里前公司某个 PHP 项目就是这样子搞的。。
    一个主入口,根据类名、方法名反射拿到 bean 然后处理请求。。
    ORZ
    areless
        44
    areless  
       2019-12-06 11:48:39 +08:00 via Android
    @lihongjie0209 并发的概念太模糊,1 连接开关在 100ms 的话,1 个连接一分钟就能承受 600 次。1000 个连接一分钟。。。普通业务很难用完啊。myisam 表的限制是硬盘分区类型的最大文件数。这只是一个想法。通过客户端 js 读服务器内存中的 key value 数据库,并且这个内存 kv 是非堵塞写 mysql 的~~~内存不足就手动清一些不常用用户,如果用户回来了,这些用户绕过 kv 直接从 mysql 读数据。mysql 主要给后台做分析用。kv 建索引清数据,日常运维。这么一个构架
    aguesuka
        45
    aguesuka  
       2019-12-06 11:49:35 +08:00 via Android
    关键字 webserver,这个技术早就有而且过时了
    est
        46
    est  
       2019-12-06 11:51:32 +08:00
    说白名单的。那还用啥反射呢。直接一个大号的 switch 拉倒。
    aguesuka
        47
    aguesuka  
       2019-12-06 11:52:43 +08:00 via Android
    Java API for XML Web Services
    janxin
        48
    janxin  
       2019-12-06 12:14:06 +08:00
    正常操作啊
    rockxsj
        49
    rockxsj  
       2019-12-06 12:35:57 +08:00 via Android
    我们也是这么干的啊 不然接口这么多写的过来?
    lqf96
        50
    lqf96  
       2019-12-06 12:42:44 +08:00 via iPhone
    这不就是 RPC 么,而且看起来有一股 gRPC 的即视感…
    wc951
        51
    wc951  
       2019-12-06 12:56:54 +08:00 via Android
    现成的协议都有了,不就是 soap 吗
    luozic
        52
    luozic  
       2019-12-06 13:02:19 +08:00 via iPhone
    强耦合,不过只玩一把,后面不维护的可以这么玩。
    wwwyiqiao
        53
    wwwyiqiao  
       2019-12-06 13:04:37 +08:00
    真 RPC
    pain400
        54
    pain400  
       2019-12-06 13:06:55 +08:00
    好蠢啊。。。
    Varobjs
        55
    Varobjs  
       2019-12-06 13:22:14 +08:00
    @eason1874 这不就是 ctroller 吗,
    > 删一个 API 的时候也是删那个类文件或者改名就可以了。

    也就是所有业务逻辑全部写到一起,哈哈
    wslsq
        56
    wslsq  
       2019-12-06 14:15:14 +08:00
    thinkphp3 就是这样做的。。
    Vegetable
        57
    Vegetable  
       2019-12-06 14:24:51 +08:00
    这没什么吧,本质上就是一个路由的形式而已.
    airfling
        58
    airfling  
       2019-12-06 15:01:49 +08:00
    你们可以把这些报名转为 md5 值,然后前台穿这些 md5 值过来,你们根据 md5 值对应的包名再反射
    outerws
        59
    outerws  
       2019-12-06 15:10:32 +08:00
    其实不太懂,java 没有动态加载机制吧?应用的场景是什么呢?现有业务接口 A,突然需要新增接口 B 实现不重启新增接口并调用?
    Rekkles
        60
    Rekkles  
       2019-12-06 16:12:19 +08:00
    约定大于配置啊 这个在 PHP 的 Laravel 和 composer 里面很常见的
    winglight2016
        61
    winglight2016  
       2019-12-06 16:39:59 +08:00
    这就是个伪动态啊,并没有什么特别的优势,还不如在登录时下发一张路由表靠谱一些。
    lj3lj3
        62
    lj3lj3  
       2019-12-06 16:54:35 +08:00
    这不就和前段时间 ThinkPHP 爆出的那个漏洞异曲同工么😂 要搞也必须再搞个白名单
    zsdroid
        63
    zsdroid  
       2019-12-06 17:02:09 +08:00
    你们 boss 还知道反射啊,厉害了。
    Felldeadbird
        64
    Felldeadbird  
       2019-12-06 17:17:35 +08:00
    不知道大家认为有安全问题 是出于什么考虑呢? 白名单怎样实现? 我想到的最多就是一个 鉴权+ token 超时认证?前端很难去基于白名单来验证吧。?这里前端是 浏览器? 还是 APP ?
    irobbin
        65
    irobbin  
       2019-12-06 17:30:06 +08:00
    耦合了
    KentY
        66
    KentY  
       2019-12-06 18:12:45 +08:00
    我觉得是 strategy pattern 的 use case.
    但描述太简要, 无法确定.
    后端一个 strategy manager 可以根据前端传过来的(不一定是类的 qualified name) token, key 等, 来选择 strategy 进行逻辑计算.
    itstudying
        67
    itstudying  
       2019-12-06 19:06:00 +08:00
    港交所页面上的接口就是,不过更骚的是他们传个类似 sql 的参数
    reus
        68
    reus  
       2019-12-06 19:20:58 +08:00
    少见多怪。
    JCZ2MkKb5S8ZX9pq
        69
    JCZ2MkKb5S8ZX9pq  
       2019-12-06 19:25:14 +08:00
    好像跟做一个 token 没差啊,只是 token 作为方法名。
    虽然不直接暴露 api,但 token 的算法不是还在前端嘛?

    这种除非搞得更骚,更容易出错,而且一错永封,那可能可以拖慢攻击效率。
    Torpedo
        70
    Torpedo  
       2019-12-06 20:18:01 +08:00
    有可维护的 graphql 啥的,就算你自己搞,最好完善一点
    gbin
        71
    gbin  
       2019-12-07 09:33:55 +08:00 via Android
    swagger 了解一下:)
    ecloud
        72
    ecloud  
       2019-12-07 18:25:54 +08:00 via iPhone
    @chengyiqun +1 我的一个产品也是这样类似的方法,DB 里维护一个对应关系表,uri -- 方法名
    waterlaw
        73
    waterlaw  
       2019-12-08 10:30:46 +08:00 via Android
    @Felldeadbird 安全问题应该是保证接口是用户有权限访问的,后端提供一个 url 接口告诉前端哪些方法可以调用(白名单),我的理解。
    waterlaw
        74
    waterlaw  
       2019-12-08 10:37:16 +08:00 via Android   ❤️ 1
    应用场景不明确,初看可以参考 #66 的方法,用策略模式 + java 注解,反射, 前端传个 id, 后端写个存常量的文件 id=com.google.UserService#method,反射根据 id 查找对应方法。
    PoetAndPoem
        75
    PoetAndPoem  
       2019-12-09 15:39:03 +08:00
    @areless 直接写 sql, 岂不是真全栈,写一个 rest 就通用了吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1196 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 23:16 · PVG 07:16 · LAX 15:16 · JFK 18:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.