当前位置 博文首页 > 风吹头蛋凉的博客:tp6api接口加密中间件

    风吹头蛋凉的博客:tp6api接口加密中间件

    作者:[db:作者] 时间:2021-06-29 19:27

    前言

    前段时间老板突然说,APP的接口能不能加密,token容易被人破解,让我想个办法,不让别人破解。我一阵搜索脑袋,发现这东西没做过,就对老板说了一句我试试。作为一个程序员,面向百度编程,已成了必备技能。网上百度一下,主要有几种方式进行加密:

    1. php后端生成密钥发给开发人员,开发人员根据密钥,把参数加上进行md5加密,生成sign。后端拿到数据根据密钥也进行加密,比对sign。安全性较强
    2. token加密,这个加密方式已经太普遍了,只要拿到用户的token,就可以随便请求,安全性一般
    3. 通过对称加密算法,该加密算法对uid+网站公钥进行时效加密,在一定时效内可用。在会员登录成功时,服务器端对该ID加密后返回给客户端,客户端每次请求接口的时候带上该参数,服务器端通过解密认证。

    综合起来还是第一种靠谱

    用tp6中间件实现加密

    主要分为两部分:

    1. 生成APP密钥,这个密钥可以是一串乱码,也可以是随机字符串。
    2. tp6中间件验证

    生成密钥

    这个可以看自己的想法来生成,只要不会重复,就不会出问题

        public static function create_unique() {
           $data = $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']    //生成密钥
               .time() . rand();
           return substr(md5(time().$data),0,24);           //截取前面24位
           //return md5(time().$data);                            //进行md5加密,并返回一个密钥
       }
    

    把这个密钥发给APP开发人员,开发人员利用密钥把参数加密。

    重点来了,tp6中间件验证密钥

    首先得写一个中间件,这个中间件对参数进行验证。

    class AppMiddleware implements MiddlewareInterface
    {
        /**  接口sign 验证
         * @param Request $request
         * @param \Closure $next
         * @param bool $force
         * @return mixed
         */
        public function handle(Request $request, \Closure $next, bool $force = true)
        {
            // 1、获取参数
            $param = $request->param();
    
            // 判断sign time_stamp 是否存在
            if(empty($param['sign']) || empty($param['time_stamp'])) return json(’密钥错误‘);
    
            // 时间判断 大于3600s返回 系统错误
    
            $time_limit = 3600;
            if(abs((int)$param['time_stamp'] - time()) > $time_limit){
                Log::error('时间超时'.time().' param= '.json_encode($param));
            }
    
    //        try {
    //            $app_api_key = env('app.api_app_key');
    //        } catch (AuthException $e) {
    //            return json(’密钥错误‘);
    //        }
    
            // 2、加入私钥并排序参数
            $app_api_key = ‘asdfasdfasdfas;   //填你刚刚生成的密钥
            if(is_null($app_api_key)){
                return  json(’密钥错误‘);
            }
            $param['api_key'] = $app_api_key;// 加入私钥
    
            // 3、过滤不需要的参数
            ksort($param); // 对数组的键(字母)进行降序排序
    
            $str = '';
            foreach ($param as $key => $val) {
                if ($key == 'sign') continue;// 符合以下条件的都不进行拼接
                $str = $str .(string)$val;// 拼接数组的值[数组的键(字母)进行降序排序]
            }
    
            // 4、生成签名
            $sign = md5($str);
    
            // 判断sign
            if(empty($sign) || $param['sign'] != $sign){
                Log::error('接口错误 sign=  '.$sign.' param= '.json_encode($param));
            }
            return $next($request);
        }
    }