快速构建第三方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);
    }

}
原文地址:https://www.cnblogs.com/sentangle/p/11777860.html