json web token 个性邮件实战

程斌 2019-02-10 PM 1166℃ 0条

场景描述

让我们来假想一下一个场景。在A用户关注了B用户的时候,系统发邮件给B用户,并且附有一个链接“点此关注A用户”。链接的地址可以是这样的:https://your.awesome-app.com/make-friend/?from_user=B&target_user=A
上面的URL主要通过URL描述来实现这个功能,这样做有一个弊端,那就是要求用户B用户是一定要先登录的。

![互相关注业务](https://upload-images.jianshu.io/upload_images/15519803-25df648e7dab3ad6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 思考:可不可以简化这个collections.deque()流程?让B用户不用登录就可以完成这个操作。
//123213123
$a = $b = $c

思路分析

前面的文章已经说到,jwt的playload可以存放自定义信息,虽然信息会暴露,不建议存放敏感信息,但是我们在该业务场景中,只需要用到用户名,用户名也不是什么敏感信息,第二个考虑点,则是需要防止篡改。
一般而言,加密算法对于不同的输入产生的输出总是不一样的。对于两个不同的输入,产生同样的输出的概率极其地小(有可能比我成世界首富的概率还小)。所以,我们就把“不一样的输入产生不一样的输出”当做必然事件来看待吧。
正确的签名

所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的。
篡改的签名

思路分析完成,只需要把我们原来的链接,后边拼接jwt加密串,即可完成该功能。如:https://your.awesome-app.com/make-friend/?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDB9.KcNaeDRMPwkRHDHsuIh1L2B01VApiu3aTOkWplFjoYI

准备工作

      $key = "example_key";
      $token = array(
            "iss" => "http://example.org",
            "aud" => "http://example.com",
            "iat" => 1356999524,
            "nbf" => 1357000000
        );
        $jwt = JWT::encode($token, $key);
        $decoded = JWT::decode($jwt, $key, array('HS256'));

        //返回的是一个obj对象
        print_r($decoded);
        $decoded_array = (array)$decoded;
        //转化为数组
        print_r($decoded_array);

编码

public function send_sys_email()
    {
        $key = "example_key";
        $token = array(
            "iss" => "https://iffor.cn",
            "aud" => "https://iffor.cn",
            "iat" => 1356999524,
            "nbf" => 1357000000,
            "from_user"=>"B",
            "target_user"=>"A"
        );
        $jwt = JWT::encode($token, $key);
        $url = "https://iffor.cn/api/jwtdemo/make_friend/?jwt=".$jwt;

        //模拟 邮件内容
        echo "亲爱的用户,新粉丝提示,刚刚【A用户】关注了您,<a href='$url'>「点击」</a>互相关注。";
    }

模拟效果图

public function make_friend()
    {
        $key = "example_key";
        $jwt = input('get.from_target');
        $decoded = JWT::decode($jwt, $key, array('HS256'));
        $decoded_array = (array)$decoded;
        dump($decoded_array);
    }

解密效果图

根据解密出来的from_user与target_user做对应的关注逻辑处理。

标签: none

非特殊说明,本博所有文章均为博主原创。

评论啦~