| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- <?php
- namespace App\Api\Service;
- use Illuminate\Support\Facades\Request;
- use Illuminate\Support\Facades\Validator;
- /**
- * API服务端总入口
- * @author Flc <2016-7-31 11:27:09>
- */
- class Server
- {
- /**
- * 请求参数
- * @var array
- */
- protected $params = [];
- /**
- * API请求Method名
- * @var string
- */
- protected $method;
- /**
- * app_id
- * @var string
- */
- protected $app_id;
- /**
- * app_secret
- * @var string
- */
- protected $app_secret;
- /**
- * 回调数据格式
- * @var string
- */
- protected $format = 'json';
- /**
- * 签名方法
- * @var string
- */
- protected $sign_method = 'md5';
- /**
- * 是否输出错误码
- * @var boolean
- */
- protected $error_code_show = false;
- /**
- * 初始化
- * @param Error $error Error对象
- */
- public function __construct(Error $error)
- {
- $this->params = Request::all();
- $this->error = $error;
- }
- /**
- * api服务入口执行
- * @param Request $request 请求参数
- * @return [type] [description]
- */
- public function run($request)
- {
- // A.1 初步校验
- $rules = [
- 'app_id' => 'required',
- 'method' => 'required',
- 'format' => 'in:,json',
- 'sign_method' => 'in:,md5',
- 'nonce' => 'required|string|min:1|max:32|',
- 'sign' => 'required',
- ];
- $messages = [
- 'app_id.required' => '1001',
- 'method.required' => '1003',
- 'format.in' => '1004',
- 'sign_method.in' => '1005',
- 'nonce.required' => '1010',
- 'nonce.string' => '1011',
- 'nonce.min' => '1012',
- 'nonce.max' => '1012',
- 'sign.required' => '1006'
- ];
- $v = Validator::make($this->params, $rules, $messages);
- if ($v->fails()) {
-
- return $this->response(['status' => false, 'code' => $v->messages()->first()]);
- }
- // A.2 赋值对象
- $this->format = !empty($this->params['format']) ? $this->params['format'] : $this->format;
- $this->sign_method = !empty($this->params['sign_method']) ? $this->params['sign_method'] : $this->sign_method;
- $this->app_id = $this->params['app_id'];
- $this->method = $this->params['method'];
- // B. appid校验
- $app = App::getInstance($this->app_id)->info();
- if (! $app)
- return $this->response(['status' => false, 'code' => '1002']);
- $this->app_secret = $app->app_secret;
- // C. 校验签名
- $signRes = config('app.debug')?['status'=>true]:$this->checkSign($this->params);
- if (! $signRes || ! $signRes['status']) {
- return $this->response(['status' => false, 'code' => $signRes['code']]);
- }
- // D. 校验接口名
- // D.1 通过方法名获取类名
- $this->method=str_replace('.','\\',$this->method);
- $className = self::getClassName($this->method);
- // D.2 判断类名是否存在
- $classPath = __NAMESPACE__ . '\\Response\\' . $className;
- if (!$className || !class_exists($classPath)) {
- return $this->response(['status' => false, 'code' => '1008']);
- }
- // D.3 判断方法是否存在
- if (! method_exists($classPath, 'run')) {
- return $this->response(['status' => false, 'code' => '1009']);
- }
- $this->classname = $classPath;
- // X 如果有uid 要验证
- if(!empty($this->params['uid'])&&!empty($this->params['token'])&&!$this->checkToken($this->params['uid'],$this->params['token'])){
- return $this->response(['status' => false, 'code' => '1014']);
- }
- // E. api接口分发
- $class = new $classPath;
- return $this->response((array) $class->run($this->params,$request));
- }
- /**
- * 检查token和uid是否一致
- * @param $uid
- * @param $token
- * @return bool
- */
- protected function checkToken($uid,$token){
- if(md5(sha1($uid))==$token){
- return true;
- }
- return false;
- }
- /**
- * 校验签名
- * @param [type] $params [description]
- * @return [type] [description]
- */
- protected function checkSign($params)
- {
- $sign = array_key_exists('sign', $params) ? $params['sign'] : '';
- if (empty($sign))
- return array('status' => false, 'code' => '1006');
- unset($params['sign']);
-
- if ($sign != $this->generateSign($params)){
- info('pay error'.$params['method']);
- // return array('status' => false, 'code' => '1007');
- }
- return array('status' => true, 'code' => '200');
- }
- /**
- * 生成签名
- * @param array $params 待校验签名参数
- * @return string|false
- */
- protected function generateSign($params)
- {
- if ($this->sign_method == 'md5')
- return $this->generateMd5Sign($params);
- return false;
- }
- /**
- * md5方式签名
- * @param array $params 待签名参数
- * @return string
- */
- protected function generateMd5Sign($params)
- {
- ksort($params);
- $tmps = array();
- foreach ($params as $k => $v) {
- $tmps[] = $k . $v;
- }
- $string = $this->app_secret . implode('', $tmps) . $this->app_secret;
- return strtoupper(md5($string));
- }
- /**
- * 通过方法名转换为对应的类名
- * @param string $method 方法名
- * @return string|false
- */
- protected function getClassName($method)
- {
- $methods = explode('.', $method);
-
- if (!is_array($methods))
- return false;
- $tmp = array();
- foreach ($methods as $value) {
- $tmp[] = ucwords($value);
- }
- $className = implode('', $tmp);
- return $className;
- }
- /**
- * 输出结果
- * @param array $result 结果
- * @return response
- */
- protected function response(array $result)
- {
- if (! array_key_exists('msg', $result) && array_key_exists('code', $result)) {
- $result['msg'] = $this->getError($result['code']);
- }
- if ($this->format == 'json') {
- return response()->json($result);
- }
- return false;
- }
- /**
- * 返回错误内容
- * @param string $code 错误码
- * @return string
- */
- protected function getError($code)
- {
- return $this->error->getError($code, $this->error_code_show);
- }
- }
|