zoukankan      html  css  js  c++  java
  • 快速构建第三方api应用

    1.使用框架和扩展

    详细请看composer.json

    "php": "^7.1.3",
    "laravel-admin-ext/config": "^1.0",
    "laravel-admin-ext/helpers": "^1.1",
    "laravel/framework": "5.8.*",
    "laravel/passport": "7.4.*",
    "laravel/tinker": "^1.0",
    "dingo/api": "2.2.*",
    "encore/laravel-admin": "1.7.7",
    "fideloper/proxy": "^4.0",
    "jxlwqq/screenfull": "^1.0",
    "mpociot/laravel-apidoc-generator": "3.17.*",
    "caouecs/laravel-lang": "~4.0"
    

    说明:

    整体	-----------------php laravel框架
    国际化扩展------------caouecs/laravel-lang
    
      
    后台管理---------------encore/laravel-admin   
    后台管理扩展-----------laravel-admin-ext/config(配置) laravel-admin-ext/helpers(小助手)jxlwqq/screenfull(全屏)
    后台模块编写-----------helpers中脚手架来快速构建
    
    前台oauth认证---------laravel中默认auth模块
    前台接口文档-----------mpociot/laravel-apidoc-generator
    
    接口管理--------------dingo/api
    oauth认证------------laravel/passport
    

    2.Dingo API+ laravel passport

    Dingo API 负责api route 配置部分
    passport 复杂oauth2.0认证

    流程:

    请求接口 =>	oauth认证授权=>重新发起请求=> 签名认证等安全认证 => 逻辑接口 => 数据返回
    

    App目录结构

    ├── Admin
    │   ├── bootstrap.php
    │   ├── Controllers
    │   │   ├── ApiLogController.php
    │   │   ├── AuthController.php
    │   │   ├── ExampleController.php
    │   │   ├── HomeController.php
    │   │   ├── OauthClientsController.php
    │   │   └── UsersController.php
    │   └── routes.php
    ├── Console
    │   └── Kernel.php
    ├── Exceptions
    │   └── Handler.php
    ├── Helpers
    │   └── functions.php
    ├── Http
    │   ├── Controllers
    │   │   ├── Api
    │   │   │   └── ProductController.php
    │   │   ├── Auth
    │   │   │   ├── ForgotPasswordController.php
    │   │   │   ├── LoginController.php
    │   │   │   ├── RegisterController.php
    │   │   │   ├── ResetPasswordController.php
    │   │   │   └── VerificationController.php
    │   │   ├── Controller.php
    │   │   └── HomeController.php
    │   ├── Kernel.php
    │   └── Middleware
    │       ├── ApiSign.php
    │       ├── Authenticate.php
    │       ├── CheckForMaintenanceMode.php
    │       ├── EncryptCookies.php
    │       ├── RedirectIfAuthenticated.php
    │       ├── TrimStrings.php
    │       ├── TrustProxies.php
    │       └── VerifyCsrfToken.php
    ├── Models
    │   ├── ApiLogModel.php
    │   ├── OauthClientsModel.php
    │   └── UsersModel.php
    ├── Observers
    │   └── ApiLogObserver.php
    ├── Providers
    │   ├── AppServiceProvider.php
    │   ├── AuthServiceProvider.php
    │   ├── BroadcastServiceProvider.php
    │   ├── EventServiceProvider.php
    │   └── RouteServiceProvider.php
    └── User.php
    

    3.核心文件代码

    ApiLogObserver api观察者类

    namespace AppObservers;
    
    class ApiLogObserver
    {
        private $startTime = 0;
        private $stopTime = 0;
    
        //开始运行时间
        public function start()
        {
            $this->startTime = $this->getMicrotime();
        }
    
        //结束时间
        public function stop()
        {
            $this->stopTime = $this->getMicrotime();
        }
    
        //开始和结束之间总时长
        public function spentTime()
        {
            return ($this->stopTime - $this->startTime);
        }
    
        private function getMicrotime()
        {
            list($usec, $sec) = explode(' ', microtime());
            return ((float)$usec + (float)$sec);
        }
    }
    

    ApiSign api签名认证

    namespace AppHttpMiddleware;
    
    use Closure;
    use IlluminateSupportFacadesDB;
    use IlluminateSupportFacadesValidator;
    
    class ApiSign
    {
        private $rule = [
            'api/test' => [
                'keyId' => 'required|numeric|max:999999',
                'sign' => 'required|max:32',
            ],
            'api/accountInfo' => [
                'keyId' => 'required|numeric|max:999999',
                'sign' => 'required|max:32',
            ],
            'api/submitOrder' => [
                'keyId' => 'required|numeric|max:999999',
                'sign' => 'required|max:32',
                'orderJson' => 'required|json',
                'updateJson' => '',
            ],
        ];
    
        /**
         * Handle an incoming request.
         *
         * @param  IlluminateHttpRequest $request
         * @param  Closure $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
    
            //1.参数的验证
            $routeName = $request->path();
            if (!empty($this->rule[$routeName]))
            {
                $result = Validator::make($request->all(), $this->rule[$routeName]);
                if ($result->fails())
                {
                    return response()->json([
                        'message' => '不合法的请求参数',
                        //'errors' => $result->errors(),
                        'code' => '40001',
                        'data' => []
                    ]);
                }
            }
    
            //2.数据库验证
            //获取用户key_screct
            $authsiteInfo = DB::connection("mysql_shop")->table('authsite')->where('key_id', $request->input("keyId"))
                ->where('status', 1)->first();
            if (empty($authsiteInfo))
            {
                return response()->json([
                    'message' => '不合法的请求参数: keyId非法',
                    'code' => '40002',
                    'data' => []
                ]);
            }
            //3.验证授权ip
            if ($authsiteInfo->ip !='' && $authsiteInfo->ip != $request->ip())
            {
                return response()->json([
                    'message' => '不合法的请求参数: ip未授权',
                    'code' => '40005',
                    'data' => []
                ]);
            }
    
            //4.验证签名
            $screctVal = $authsiteInfo->key_secret;
            $requestArr = $request->input();
            unset($requestArr['sign']);
            //var_dump($this->getSign($requestArr, $screctVal));
            if ($request->input("sign") != $this->getSign($requestArr, $screctVal))
            {
                return response()->json([
                    'message' => '不合法的请求参数: 签名sign错误',
                    'code' => '40003',
                    'data' => []
                ]);
            }
            return $next($request);
        }
    
        /**
         * 获取sign
         */
        private function getSign($tempArr, $randStr = '')
        {
            ksort($tempArr);
            $signStr = "";
            foreach ($tempArr as $key => $val)
            {
                $signStr .= $key . "=" . $val . "&";
            }
            $signStr = trim($signStr, "&");
            return md5($signStr . $randStr);
        }
    }
    

    DemoController 接口逻辑类

    <?php
    /**
     * Created by PhpStorm.
     * User: 
     * Date: 2019/10/22
     * Time: 15:17
     */
    
    namespace AppHttpControllersApi;
    
    
    use AppHttpControllersController;
    use AppObserversApiLogObserver;
    use IlluminateHttpRequest;
    use IlluminateSupportFacadesDB;
    
    /**
     * @group 生产系统接口
     *
     * 接口为第三商城提供api接口,通过api接口可以提交绿爱生产系统!
     */
    class DemoController extends Controller
    {
        protected $apiLogObserver;
        protected $dbShop;
    
        private $result = [
            'code' => 0,
            'message' => "",
            'data' => []
        ];
        //通过验证后开始提交标识
        private $get_ins_id = 0;
    
        public function __construct(ApiLogObserver $apiLogObserver)
        {
            $this->apiLogObserver = $apiLogObserver;
            $this->apiLogObserver->start();
            //商城数据库
            $this->dbShop = DB::connection("mysql_shop");
        }
    
        /**
         *
         * 测试接口是否可用
         *
         * @bodyParam keyId string required 用户的appkey.
         * @bodyParam sign string required 用户的签名.
         *
         * @authenticated
         *
         * @response {
         *  "code": 0,
         *  "massage": "测试可以正常使用",
         *  "data": []
         * }
         */
    
        public function test()
        {
            $this->result['massage'] = "测试可以正常使用";
    
            return response()->json($this->result);
        }
    
        /**
         *
         * 查询用户平台的账户信息
         *
         * @bodyParam keyId string required 用户的appkey.
         * @bodyParam sign string required 用户的签名.
         *
         * @authenticated
         *
         * @response {
         *  "code": 0,
         *  "massage": "查询成功",
         *  "data": ['balance']
         * }
         */
        public function getAccountInfo(Request $request)
        {
            // 验证
            $keyId = $request->input('keyId');
            $authsiteInfo = $this->dbShop->table('authsite')->select("balance")->where('status', 1)->where('key_id', $keyId)->first();
    
            if (empty($authsiteInfo))
            {
    
                $this->result['code'] = "40002";
                $this->result['message'] = "不合法的请求参数: key_id非法";
                return $this->returnRespone();
            }
    
            //数据返回
            $this->result['data']['balance'] = $authsiteInfo->balance;
            $this->result['message'] = "查询成功";
            return $this->returnRespone();
        }
    
        // 返回信息
        private function returnRespone()
        {
    
            $this->apiLogObserver->stop(); 
            return response()->json($this->result);
        }
    
    }
  • 相关阅读:
    EKLM3S8962之LED
    [uClinuxdev] detecting stack overflow
    Eclipse换行符
    EKLM3S8962之OLED
    Windows 环境下 GNU ARM 开发环境建立
    关于阻焊层和助焊层的理解
    MISRA C 2004中文版
    对话框托盘程序实现源码
    VC++中四种进程或线程同步互斥的控制方法
    Windows线程同步与互斥技术总结
  • 原文地址:https://www.cnblogs.com/sentangle/p/11777860.html
Copyright © 2011-2022 走看看