Compare commits
10 Commits
57335f98ce
...
1aedddc66e
Author | SHA1 | Date | |
---|---|---|---|
1aedddc66e | |||
|
445f9dd037 | ||
|
436a084581 | ||
|
6c54737d13 | ||
|
5aaeaa0499 | ||
|
1700ac3c87 | ||
|
33ca037634 | ||
|
d1d1802b14 | ||
|
87970d17ae | ||
|
d86fe14e49 |
102
README.md
Normal file
102
README.md
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
# Internal API Server/Client(PHP版)
|
||||||
|
|
||||||
|
|
||||||
|
> 该项目使用 composer 来完成加载
|
||||||
|
|
||||||
|
执行
|
||||||
|
```bash
|
||||||
|
composer config repositories.php-internal-api-client vcs git@git.int.haowumc.com:arch/php-internal-api-client.git
|
||||||
|
composer require arch/php-internal-api-client
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 如何使用
|
||||||
|
|
||||||
|
#### Server
|
||||||
|
|
||||||
|
* 注册中间件
|
||||||
|
|
||||||
|
```php
|
||||||
|
$app->routeMiddleware([
|
||||||
|
'internal' => PdInternalApi\Middleware\InternalApi::class,
|
||||||
|
]);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* 增加配置文件:```config/internal_api.php``` , 在server数组中为调用方增加 secret。
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* 对内部其他系统提供api
|
||||||
|
*
|
||||||
|
* 格式为:
|
||||||
|
* 调用方标识 => 调用方secret
|
||||||
|
*/
|
||||||
|
'server' => [
|
||||||
|
// app id => app secret
|
||||||
|
'{{app name}}' => env('INTERNAL_SERVER_{{app name}}_SECRET'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
* 在项目 .env 文件中增加如下配置
|
||||||
|
|
||||||
|
```
|
||||||
|
INTERNAL_SERVER_{{app name}}_SECRET=323232323
|
||||||
|
```
|
||||||
|
|
||||||
|
* 在路由中启用中间件
|
||||||
|
|
||||||
|
```php
|
||||||
|
$route->group(['middleware'=>'internal'],function()use($router){
|
||||||
|
//这里添加对应路由
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Client
|
||||||
|
|
||||||
|
* 注册服务
|
||||||
|
|
||||||
|
```PHP
|
||||||
|
$app->register(PdInternalApi\ServiceProvider::class);
|
||||||
|
```
|
||||||
|
* 增加配置文件:```config/internal_api.php``` , 在server数组中为调用方增加 secret。
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* 配置可以使用的内部系统
|
||||||
|
*/
|
||||||
|
'client' => [
|
||||||
|
/**
|
||||||
|
* key 为 api 项目的名称。
|
||||||
|
* 数组为该系统的配置,由该系统的负责人提供
|
||||||
|
*/
|
||||||
|
'{app name}' => [
|
||||||
|
'base_uri' => env('INTERNAL_CLIENT_{{app name}}_URI', ''),
|
||||||
|
'appid' => env('INTERNAL_CLIENT_{{app name}}_APPID', ''),
|
||||||
|
'secret' => env('INTERNAL_CLIENT_{{app name}}_SECRET', ''),
|
||||||
|
'timeout' => 30,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
* 在项目 .env 文件中增加如下配置
|
||||||
|
|
||||||
|
```
|
||||||
|
INTERNAL_CLIENT_{app name}_URI=http://test.in.haowumc.com/
|
||||||
|
INTERNAL_CLIENT_{app name}_APPID=test
|
||||||
|
INTERNAL_CLIENT_{app name}_SECRET=sdfsdfsdf
|
||||||
|
```
|
||||||
|
|
||||||
|
* 调用
|
||||||
|
|
||||||
|
```php
|
||||||
|
$api = app('internal.api.{{app name}}')
|
||||||
|
$resp = $api->call('{{URI}}',$params);
|
||||||
|
```
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "pd_arch/internal_api",
|
"name": "paidian/php-internal-api-client",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"require": {
|
"require": {
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
"guzzlehttp/guzzle": "^6.3",
|
||||||
|
@ -7,7 +7,7 @@
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"InternalApi\\": "src/"
|
"PdInternalApi\\": "src/"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"src/helpers.php"
|
"src/helpers.php"
|
||||||
|
|
1194
composer.lock
generated
1194
composer.lock
generated
File diff suppressed because it is too large
Load Diff
|
@ -1,29 +1,19 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace InternalApi;
|
namespace PdInternalApi;
|
||||||
|
|
||||||
class Client
|
class Client
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $currentApp;
|
protected $service_name;
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
public function __construct($config)
|
public function __construct($service_name, $config)
|
||||||
{
|
{
|
||||||
|
$this->service_name = $service_name;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $app
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function app($app)
|
|
||||||
{
|
|
||||||
if (isset($this->config[$app]))
|
|
||||||
$this->currentApp = $app;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用api,如果状态码不为200则抛出异常
|
* 调用api,如果状态码不为200则抛出异常
|
||||||
* @param $uri
|
* @param $uri
|
||||||
|
@ -33,8 +23,7 @@ class Client
|
||||||
*/
|
*/
|
||||||
public function call($uri, $params)
|
public function call($uri, $params)
|
||||||
{
|
{
|
||||||
$config = array_merge(['timeout' => 3],
|
$config = array_merge(['timeout' => 3], $this->config);
|
||||||
$this->config[$this->currentApp]);
|
|
||||||
$secret = $config['secret'];
|
$secret = $config['secret'];
|
||||||
unset($config['secret']);
|
unset($config['secret']);
|
||||||
$client = new \GuzzleHttp\Client($config);
|
$client = new \GuzzleHttp\Client($config);
|
||||||
|
@ -42,10 +31,10 @@ class Client
|
||||||
$params['timestamp'] = time();
|
$params['timestamp'] = time();
|
||||||
$params['sign'] = sign($params, $secret);
|
$params['sign'] = sign($params, $secret);
|
||||||
$resp = $client->post($uri, ['form_params' => $params]);
|
$resp = $client->post($uri, ['form_params' => $params]);
|
||||||
if ($resp->getStatusCode() == 200) {
|
if ($resp->getStatusCode() != 200) {
|
||||||
return \GuzzleHttp\json_decode($resp->getBody(), true);
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return \GuzzleHttp\json_decode($resp->getBody(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,68 +1,86 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace InternalApi\Middleware;
|
namespace PdInternalApi\Middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use function InternalApi\sign;
|
use function PdInternalApi\sign;
|
||||||
|
|
||||||
class InternalApi
|
class InternalApi
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
app()->configure('internal_api');
|
app()->configure('internal_api');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function isClientIPPermitted($ip)
|
||||||
* Handle an incoming request.
|
{
|
||||||
*
|
if (!app()->environment('production', 'staging')) {
|
||||||
* @param \Illuminate\Http\Request $request
|
return true;
|
||||||
* @param \Closure $next
|
}
|
||||||
* @return mixed
|
if (Str::startsWith($ip, [
|
||||||
*/
|
'127.0.0.1',
|
||||||
public function handle($request, Closure $next)
|
//局域网
|
||||||
{
|
'192.168.',
|
||||||
$ip = $request->getClientIp();
|
//vpc
|
||||||
|
'10.0.',
|
||||||
|
//pod network
|
||||||
|
'172.20.',
|
||||||
|
//北京办公区
|
||||||
|
'172.16.'
|
||||||
|
])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Str::startsWith($ip, [
|
/**
|
||||||
'127.0.0.', '192.168.', '10.0.'
|
* Handle an incoming request.
|
||||||
])) {
|
*
|
||||||
return new JsonResponse('', 404);
|
* @param \Illuminate\Http\Request $request
|
||||||
}
|
* @param \Closure $next
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle($request, Closure $next)
|
||||||
|
{
|
||||||
|
$ip = $request->getClientIp();
|
||||||
|
if (!$this->isClientIPPermitted($ip)) {
|
||||||
|
return new JsonResponse("$ip is forbidden", 403);
|
||||||
|
}
|
||||||
|
|
||||||
$params = $request->all();
|
$params = $request->all();
|
||||||
|
|
||||||
if (empty($params['appid'])) {
|
if (empty($params['appid'])) {
|
||||||
$data = ['error' => 'require appid',];
|
$data = ['error' => 'require appid',];
|
||||||
return new JsonResponse($data, 403);
|
return new JsonResponse($data, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($params['timestamp'])) {
|
if (empty($params['timestamp'])) {
|
||||||
$data = ['error' => 'require time',];
|
$data = ['error' => 'require time',];
|
||||||
return new JsonResponse($data, 403);
|
return new JsonResponse($data, 403);
|
||||||
} elseif (intval($params['timestamp']) + 60 < time()) {
|
} else if (intval($params['timestamp']) + 60 < time()) {
|
||||||
$data = ['error' => 'sign expired',];
|
$data = ['error' => 'sign expired',];
|
||||||
return new JsonResponse($data, 403);
|
return new JsonResponse($data, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
$key = config('internal_api.server.' . $params['appid']);
|
$key = config('internal_api.server.' . $params['appid']);
|
||||||
|
|
||||||
if (empty($key)) {
|
if (empty($key)) {
|
||||||
$data = ['error' => 'config error',];
|
$data = ['error' => 'config error',];
|
||||||
return new JsonResponse($data, 403);
|
return new JsonResponse($data, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sign = sign($params, $key);
|
$sign = sign($params, $key);
|
||||||
if ($sign != $params['sign']) {
|
if ($sign != $params['sign']) {
|
||||||
$data = [
|
$data = [
|
||||||
'error' => 'sign error',
|
'error' => 'sign error',
|
||||||
];
|
];
|
||||||
return new JsonResponse($data, 403);
|
return new JsonResponse($data, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
40
src/ServiceProvider.php
Normal file
40
src/ServiceProvider.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PdInternalApi;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ServiceProvider extends \Illuminate\Support\ServiceProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
public function boot(){
|
||||||
|
Request::setTrustedProxies([
|
||||||
|
//pod network
|
||||||
|
'172.20.0.0/16',
|
||||||
|
//vpc
|
||||||
|
'10.0.0.0/16',
|
||||||
|
//local
|
||||||
|
'127.0.0.1',
|
||||||
|
//北京办公区
|
||||||
|
'172.16.0.0/16',
|
||||||
|
//aliyun slb
|
||||||
|
'100.116.0.0/16',
|
||||||
|
], Request::HEADER_X_FORWARDED_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
$this->app->configure('internal_api');
|
||||||
|
foreach (config('internal_api.client') as $service_name => $config) {
|
||||||
|
$this->app->singleton('internal.api.' . $service_name, function () use ($service_name, $config) {
|
||||||
|
return new Client($service_name, $config);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace InternalApi\ServiceProvider;
|
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
|
||||||
use InternalApi\Client;
|
|
||||||
|
|
||||||
class InternalApiServiceProvider extends ServiceProvider
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Register any application services.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
$this->app->configure('internal_api');
|
|
||||||
$this->app->singleton('internal.api', function () {
|
|
||||||
return new Client(config('internal_api.client'));
|
|
||||||
});
|
|
||||||
foreach (config('internal_api.client') as $key => $config) {
|
|
||||||
$this->app->singleton('internal.api.' . $key, function () use ($key) {
|
|
||||||
return $this->app['internal.api']->app($key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
36
src/config/internal_api.php
Normal file
36
src/config/internal_api.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
return [
|
||||||
|
/**
|
||||||
|
* 对内部其他系统提供api
|
||||||
|
*
|
||||||
|
* 格式为:
|
||||||
|
* 调用方标识 => 调用方secret
|
||||||
|
*/
|
||||||
|
'server' => [
|
||||||
|
// app id => app secret
|
||||||
|
'finance' => 'a249f0e40e31877adedd76fac6c6c116',
|
||||||
|
'mall' => '8b54fdc7b317906d93c83152be5f956b',
|
||||||
|
'xiaoke' => '8b54fdc7b317906d93c83152be5f956b',
|
||||||
|
],
|
||||||
|
/**
|
||||||
|
* 配置可以使用的内部系统
|
||||||
|
*/
|
||||||
|
'client' => [
|
||||||
|
/**
|
||||||
|
* key 为 api 项目的名称。
|
||||||
|
* 数组为该系统的配置,由该系统的负责人提供
|
||||||
|
*/
|
||||||
|
'finance' => [
|
||||||
|
'base_uri' => env('INTERNAL_CLIENT_FINANCE_URI', ''),
|
||||||
|
'appid' => env('INTERNAL_CLIENT_FINANCE_APPID', ''),
|
||||||
|
'secret' => env('INTERNAL_CLIENT_FINANCE_SECRET', ''),
|
||||||
|
'timeout' => 30,
|
||||||
|
],
|
||||||
|
'mall' => [
|
||||||
|
'base_uri' => env('INTERNAL_CLIENT_MALL_URI', ''),
|
||||||
|
'appid' => env('INTERNAL_CLIENT_MALL_APPID', ''),
|
||||||
|
'secret' => env('INTERNAL_CLIENT_MALL_SECRET', ''),
|
||||||
|
'timeout' => 3,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace InternalApi;
|
namespace PdInternalApi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 签名
|
* 签名
|
||||||
|
|
Loading…
Reference in New Issue
Block a user