V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
ericgui
V2EX  ›  分享创造

如果开源库有问题,还是希望自己能够有解决问题的能力,比如 PHP 里的一个 jwt 库, api 像屎一样,你怎么办?

  •  
  •   ericgui · 2019-01-06 04:28:18 +08:00 · 3024 次点击
    这是一个创建于 2129 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://github.com/lcobucci/jwt

    比如这个库,其实有不少坑的,api 真的非常不友好,误导人,怎么办?

    困扰 2 天的问题:

    • jwt token 的签发: $token= (new Builder())->....->getToken();这尼玛其实是个object,不是string,所以你必须用(string)$token得到最后的 token string;

    • jwt token signature 的验证:同样,官方文档里是这样的:var_dump($token->verify(...)),这个方法的搞笑地方在于,$token 是个object,如果客户端发送的是一个 token string,你怎么验证呢?

    总之,这个沙雕文档能把你坑死了。

    后来我只好参考了firebase php-jwt这个库的代码,用原生 PHP 函数,写了一个只针对RS256的验证方法。

    前段时间我还问了一个问题:如果开源库有问题能不能骂?其实我个人认为是可以骂的,因为开源绝对不是开源库作者对别人的施舍,他有义务的。参考 ant design 圣诞地雷事件。

    至于某些人说爱用用,不用滚,你就只配吃屎。

    既然我把这个帖子发在分享创造这个节点,我还是希望大家能够访问我的博客,看一下具体内容: https://superphp.org/2018/375.html https://superphp.org/2019/378.html

    这个库应用范围还是很广的,每月很多下载量,我觉得不止我一个人遇到类似的问题,希望对你有帮助。

    第 1 条附言  ·  2019-01-06 05:45:36 +08:00
    好吧,请看 4 楼,我说的其实是错的。
    19 条回复    2019-01-08 10:58:24 +08:00
    feiyuanqiu
        1
    feiyuanqiu  
       2019-01-06 04:53:21 +08:00
    看了一下,觉得这个库的 API 挺好的,大概因为我是写 java 的吧...

    「...这尼玛其实是个 object,不是 string,所以你必须用(string)$token 得到最后的 token string;」
    接口里定义了 toString 方法,应该不算很隐蔽吧
    https://github.com/lcobucci/jwt/blob/master/src/Token.php#L54

    「...这个方法的搞笑地方在于,$token 是个 object,如果客户端发送的是一个 token string,你怎么验证呢?
    https://github.com/lcobucci/jwt/blob/3.2/README.md#parsing-from-strings


    当然如果不符合你的使用习惯,可以自己再封装一下
    nightcat
        2
    nightcat  
       2019-01-06 04:59:20 +08:00
    不要太冲动,先给项目发 issue 或者提交修复代码,如果作者不理会或者不接受再骂也不迟
    ericgui
        3
    ericgui  
    OP
       2019-01-06 05:01:02 +08:00
    @feiyuanqiu 这个__toString()是 PHP 特有的魔术方法,一般是自动触发,而不是类似 java 那种 someOb.toString()手动调用

    parse 仅仅是解析 jwt token 的 header 和 payload,而是没法验证这个 token 是否是你签发的(验证签名)。

    他的文档是有问题的
    feiyuanqiu
        4
    feiyuanqiu  
       2019-01-06 05:18:04 +08:00 via Android
    @ericgui 我写过 php,__toString 是个很基础的方法,说句冒犯的话,可能你需要再深入地看看 php 文档

    通过 parse 方法,可以将字符串解析为 token 对象,之后就可以使用 verify 或 validate 方法做验证了。

    你如果不喜欢这种面向对象的使用方式,完全可以将这个步骤封装为函数,或者向作者请求提供一份函数 facade
    ericgui
        5
    ericgui  
    OP
       2019-01-06 05:36:21 +08:00
    @feiyuanqiu 不冒犯,水平不行也是正常。
    ericgui
        6
    ericgui  
    OP
       2019-01-06 05:45:11 +08:00
    @feiyuanqiu 你说的对。所以我发现这个面向对象思想还是我欠缺的。
    ericgui
        7
    ericgui  
    OP
       2019-01-06 06:09:16 +08:00
    @feiyuanqiu 不过老兄,这文档确实有问题,哎,不说了,反正挺痛苦。
    suley
        8
    suley  
       2019-01-06 10:33:26 +08:00
    @ericgui 还是没看出来有什么问题,估计还是你自己的问题……
    gouchaoer
        9
    gouchaoer  
       2019-01-06 10:40:27 +08:00 via Android
    保证 IDE 有 typehint,然后 xdebug 单步调试就嗖嗖的写业务吧
    iyaozhen
        10
    iyaozhen  
       2019-01-06 11:33:57 +08:00 via Android
    老哥,你这是没写过 JAVA 呀,JAVA 面向对象比这更严重
    zn
        11
    zn  
       2019-01-06 11:43:52 +08:00 via iPhone   ❤️ 1
    楼主你这是没怎么用过面向对象编程方式,大部分时间都在写意大利面条式代码吧。
    lshero
        12
    lshero  
       2019-01-06 11:47:46 +08:00
    不想依赖第三方库 hash_hmac 可以帮你解决大部分问题
    ericgui
        13
    ericgui  
    OP
       2019-01-06 12:28:39 +08:00
    @zn 是的,php 程序员嘛,哈哈
    ericgui
        14
    ericgui  
    OP
       2019-01-06 12:30:58 +08:00
    @lshero 感谢老铁,我研究一下哈
    ericgui
        15
    ericgui  
    OP
       2019-01-06 12:31:59 +08:00
    @iyaozhen Java 学了 3 个月,感觉太墨迹,转投 php 了
    noli
        16
    noli  
       2019-01-06 13:37:24 +08:00 via iPhone   ❤️ 1
    这标题和所在话题的放置方式浪费了我不少时间,
    原来楼主创造了一个让别人检验他水平的机会。
    希望后来者早点看到我这一条。
    话题不对坚决不回复。
    iyaozhen
        17
    iyaozhen  
       2019-01-07 10:31:57 +08:00 via Android
    @ericgui 殊途同归,PHP 代码项目复杂了也一样。
    eb22fbb4
        18
    eb22fbb4  
       2019-01-07 16:15:15 +08:00
    第一点,Lcobucci\JWT\Builder 类的 getToken 返回的 object 是一个 Lcobucci\JWT\Token 实例,而 Lcobucci\JWT\Token 是有一个 __toString 方法的,这个方法保证了即使你直接 echo
    的时候也是返回字符串,这种用法在面向对象里很常见的,不管是强面向对象的框架(比如 Symfony )还是其它语言(比如 JAVA ),所以并不觉得这样会不友好:

    https://github.com/lcobucci/jwt/blob/3.2.5/src/Builder.php#L264

    第二点,客户端传过来的 token string 只需要使用 Lcobucci\JWT\Parse 中的 parse 方法生成一个新的 Lcobucci\JWT\Token 实例:

    具体实现在:

    https://github.com/lcobucci/jwt/blob/3.2.5/src/Token.php#L191


    实例代码:
    $parser = new \Lcobucci\JWT\Parse();
    $token = $parser->parse($_GET['token']);

    而这个 $token 实例,是和你上一步的 Lcobucci\JWT\Token 是一样的,有了这个 $token 实例之后,你只需要在 verify 里验证你的 singer 就可以了,根本不存在你说的客户端传过来是个 string 无法验证这种问题。

    所以,用以上两点来证明这个包坑多,不友好,完全没有说服力。
    daguaochengtang
        19
    daguaochengtang  
       2019-01-08 10:58:24 +08:00
    @eb22fbb4 你这个头像,真皮沙发
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1122 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 18:38 · PVG 02:38 · LAX 10:38 · JFK 13:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.