diff --git a/application/http/middleware/WikiAuth.php b/application/http/middleware/WikiAuth.php new file mode 100644 index 0000000..f1dc0be --- /dev/null +++ b/application/http/middleware/WikiAuth.php @@ -0,0 +1,46 @@ + + */ + public function handle($request, \Closure $next) { + $header = config('apiadmin.CROSS_DOMAIN'); + $ApiAuth = $request->header('apiAuth', ''); + if ($ApiAuth) { + $userInfo = cache('Login:' . $ApiAuth); + if (!$userInfo) { + $userInfo = cache('WikiLogin:' . $ApiAuth); + } else { + $userInfo = json_decode($userInfo, true); + $userInfo['app_id'] = -1; + } + if (!$userInfo || !isset($userInfo['id'])) { + return json([ + 'code' => ReturnCode::AUTH_ERROR, + 'msg' => 'ApiAuth不匹配', + 'data' => [] + ])->header($header); + } else { + $request->API_WIKI_USER_INFO = $userInfo; + } + + return $next($request); + } else { + return json([ + 'code' => ReturnCode::AUTH_ERROR, + 'msg' => '缺少ApiAuth', + 'data' => [] + ])->header($header); + } + } +} diff --git a/application/wiki/controller/Api.php b/application/wiki/controller/Api.php index 2ca331e..d90a01e 100644 --- a/application/wiki/controller/Api.php +++ b/application/wiki/controller/Api.php @@ -7,7 +7,13 @@ namespace app\wiki\controller; +use app\model\AdminApp; +use app\model\AdminFields; +use app\model\AdminGroup; +use app\model\AdminList; +use app\util\DataType; use app\util\ReturnCode; +use app\util\Tools; class Api extends Base { @@ -56,4 +62,104 @@ class Api extends Base { return $this->buildSuccess($result); } + public function login() { + $appId = $this->request->post('username'); + $appSecret = $this->request->post('password'); + + $appInfo = AdminApp::get(['app_id' => $appId, 'app_secret' => $appSecret]); + if (!empty($appInfo)) { + if ($appInfo->app_status) { + //保存用户信息和登录凭证 + $appInfo = $appInfo->toArray(); + + $apiAuth = md5(uniqid() . time()); + cache('WikiLogin:' . $apiAuth, $appInfo, config('apiadmin.ONLINE_TIME')); + cache('WikiLogin:' . $appInfo['id'], $apiAuth, config('apiadmin.ONLINE_TIME')); + $appInfo['apiAuth'] = $apiAuth; + + return $this->buildSuccess($appInfo, '登录成功'); + } else { + return $this->buildFailed(ReturnCode::LOGIN_ERROR, '当前应用已被封禁,请联系管理员'); + } + } else { + return $this->buildFailed(ReturnCode::LOGIN_ERROR, 'AppId或AppSecret错误'); + } + } + + public function groupList() { + $groupInfo = AdminGroup::all(); + $groupInfo = Tools::buildArrFromObj($groupInfo, 'hash'); + $apiInfo = AdminList::all(); + $apiInfo = Tools::buildArrFromObj($apiInfo, 'hash'); + + $app_api_show = json_decode($this->appInfo['app_api_show'], true); + + $listInfo = []; + foreach ($app_api_show as $key => $item) { + $_listInfo = $groupInfo[$key]; + foreach ($item as $apiItem) { + $_listInfo['api_info'][] = $apiInfo[$apiItem]; + } + + $listInfo[] = $_listInfo; + } + + return $this->buildSuccess($listInfo); + } + + public function detail() { + $groupHash = $this->request->route('groupHash'); + $hash = $this->request->route('hash', ''); + $this->appInfo['app_api_show'] = json_decode($this->appInfo['app_api_show'], true); + if (!isset($this->appInfo['app_api_show'][$groupHash]) || empty($this->appInfo['app_api_show'][$groupHash])) { + $this->error('请求非法', url('/wiki/index')); + } + + if (!$hash) { + $hash = $this->appInfo['app_api_show'][$groupHash][0]; + } else { + if (!in_array($hash, $this->appInfo['app_api_show'][$groupHash])) { + $this->error('请求非法', url('/wiki/index')); + } + } + + $apiList = (new AdminList())->whereIn('hash', $this->appInfo['app_api_show'][$groupHash])->where(['group_hash' => $groupHash])->select(); + $apiList = Tools::buildArrFromObj($apiList); + $apiList = Tools::buildArrByNewKey($apiList, 'hash'); + + if (!$hash) { + $hash = $this->appInfo['app_api_show'][$groupHash][0]; + } + $detail = $apiList[$hash]; + + $request = AdminFields::all(['hash' => $hash, 'type' => 0]); + $response = AdminFields::all(['hash' => $hash, 'type' => 1]); + $dataType = array( + DataType::TYPE_INTEGER => 'Integer', + DataType::TYPE_STRING => 'String', + DataType::TYPE_BOOLEAN => 'Boolean', + DataType::TYPE_ENUM => 'Enum', + DataType::TYPE_FLOAT => 'Float', + DataType::TYPE_FILE => 'File', + DataType::TYPE_ARRAY => 'Array', + DataType::TYPE_OBJECT => 'Object', + DataType::TYPE_MOBILE => 'Mobile' + ); + + $groupInfo = AdminGroup::get(['hash' => $groupHash]); + $groupInfo->hot = $groupInfo->hot + 1; + $groupInfo->save(); + + return view('', [ + 'groupInfo' => $groupInfo->toArray(), + 'request' => $request, + 'response' => $response, + 'dataType' => $dataType, + 'apiList' => $apiList, + 'detail' => $detail, + 'hash' => $hash, + 'groupHash' => $groupHash + ]); + } + } diff --git a/application/wiki/controller/Base.php b/application/wiki/controller/Base.php index 34ccd17..a18656e 100644 --- a/application/wiki/controller/Base.php +++ b/application/wiki/controller/Base.php @@ -9,25 +9,15 @@ namespace app\wiki\controller; use app\util\ReturnCode; -use think\facade\Config; use think\Controller; -use think\exception\HttpResponseException; -use think\facade\Request; -use think\facade\Response; -use think\facade\View as ViewTemplate; -use think\facade\Url; class Base extends Controller { protected $appInfo; - public function checkLogin() { - $appInfo = session('app_info'); - if ($appInfo) { - $this->appInfo = json_decode($appInfo, true); - } else { - $this->redirect(url('/wiki/login')); - } + public function __construct() { + parent::__construct(); + $this->appInfo = $this->request->API_WIKI_USER_INFO; } public function buildSuccess($data, $msg = '操作成功', $code = ReturnCode::SUCCESS) { @@ -50,62 +40,4 @@ class Base extends Controller { return json($return); } - public function error($msg = '', $url = null, $data = '', $wait = 3, array $header = []) { - if (is_null($url)) { - $url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);'; - } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { - $url = Url::build($url); - } - - $type = 'html'; - $result = [ - 'code' => 0, - 'msg' => $msg, - 'data' => $data, - 'url' => $url, - 'wait' => $wait, - ]; - - if ('html' == strtolower($type)) { - $template = Config::get('template'); - $view = Config::get('view_replace_str'); - - $result = ViewTemplate::instance($template, $view) - ->fetch(Config::get('dispatch_error_tmpl'), $result); - } - - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - - public function success($msg = '', $url = null, $data = '', $wait = 3, array $header = []) { - if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) { - $url = Request::instance()->server('HTTP_REFERER'); - } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) { - $url = Url::build($url); - } - - $type = 'html'; - $result = [ - 'code' => 1, - 'msg' => $msg, - 'data' => $data, - 'url' => $url, - 'wait' => $wait, - ]; - - if ('html' == strtolower($type)) { - $template = Config::get('template'); - $view = Config::get('view_replace_str'); - - $result = ViewTemplate::instance($template, $view) - ->fetch(Config::get('dispatch_success_tmpl'), $result); - } - - $response = Response::create($result, $type)->header($header); - - throw new HttpResponseException($response); - } - } diff --git a/application/wiki/controller/Index.php b/application/wiki/controller/Index.php deleted file mode 100644 index 3cc908a..0000000 --- a/application/wiki/controller/Index.php +++ /dev/null @@ -1,178 +0,0 @@ - - */ - -namespace app\wiki\controller; - - -use app\model\AdminApp; -use app\model\AdminFields; -use app\model\AdminGroup; -use app\model\AdminList; -use app\util\DataType; -use app\util\ReturnCode; -use app\util\Tools; - -class Index extends Base { - - /** - * 获取应用列表 - * @return \think\response\View - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function index() { - $this->checkLogin(); - - $groupInfo = AdminGroup::all(); - $groupInfo = Tools::buildArrFromObj($groupInfo); - $groupInfo = Tools::buildArrByNewKey($groupInfo, 'hash'); - - $this->appInfo = AdminApp::get(['app_id' => $this->appInfo['app_id']]); - $this->appInfo['app_api_show'] = json_decode($this->appInfo['app_api_show'], true); - - return view('', [ - 'groupInfo' => $groupInfo, - 'appInfo' => $this->appInfo - ]); - } - - public function detail() { - $this->checkLogin(); - - $groupHash = $this->request->route('groupHash'); - $hash = $this->request->route('hash', ''); - $this->appInfo['app_api_show'] = json_decode($this->appInfo['app_api_show'], true); - if (!isset($this->appInfo['app_api_show'][$groupHash]) || empty($this->appInfo['app_api_show'][$groupHash])) { - $this->error('请求非法', url('/wiki/index')); - } - - if (!$hash) { - $hash = $this->appInfo['app_api_show'][$groupHash][0]; - } else { - if (!in_array($hash, $this->appInfo['app_api_show'][$groupHash])) { - $this->error('请求非法', url('/wiki/index')); - } - } - - $apiList = (new AdminList())->whereIn('hash', $this->appInfo['app_api_show'][$groupHash])->where(['group_hash' => $groupHash])->select(); - $apiList = Tools::buildArrFromObj($apiList); - $apiList = Tools::buildArrByNewKey($apiList, 'hash'); - - if (!$hash) { - $hash = $this->appInfo['app_api_show'][$groupHash][0]; - } - $detail = $apiList[$hash]; - - $request = AdminFields::all(['hash' => $hash, 'type' => 0]); - $response = AdminFields::all(['hash' => $hash, 'type' => 1]); - $dataType = array( - DataType::TYPE_INTEGER => 'Integer', - DataType::TYPE_STRING => 'String', - DataType::TYPE_BOOLEAN => 'Boolean', - DataType::TYPE_ENUM => 'Enum', - DataType::TYPE_FLOAT => 'Float', - DataType::TYPE_FILE => 'File', - DataType::TYPE_ARRAY => 'Array', - DataType::TYPE_OBJECT => 'Object', - DataType::TYPE_MOBILE => 'Mobile' - ); - - $groupInfo = AdminGroup::get(['hash' => $groupHash]); - $groupInfo->hot = $groupInfo->hot + 1; - $groupInfo->save(); - - return view('', [ - 'groupInfo' => $groupInfo->toArray(), - 'request' => $request, - 'response' => $response, - 'dataType' => $dataType, - 'apiList' => $apiList, - 'detail' => $detail, - 'hash' => $hash, - 'groupHash' => $groupHash - ]); - } - - public function calculation() { - $this->checkLogin(); - - return view(); - } - - public function errorCode() { - $this->checkLogin(); - $codeArr = ReturnCode::getConstants(); - $errorInfo = array( - ReturnCode::SUCCESS => '请求成功', - ReturnCode::INVALID => '非法操作', - ReturnCode::DB_SAVE_ERROR => '数据存储失败', - ReturnCode::DB_READ_ERROR => '数据读取失败', - ReturnCode::CACHE_SAVE_ERROR => '缓存存储失败', - ReturnCode::CACHE_READ_ERROR => '缓存读取失败', - ReturnCode::FILE_SAVE_ERROR => '文件读取失败', - ReturnCode::LOGIN_ERROR => '登录失败', - ReturnCode::NOT_EXISTS => '不存在', - ReturnCode::JSON_PARSE_FAIL => 'JSON数据格式错误', - ReturnCode::TYPE_ERROR => '类型错误', - ReturnCode::NUMBER_MATCH_ERROR => '数字匹配失败', - ReturnCode::EMPTY_PARAMS => '丢失必要数据', - ReturnCode::DATA_EXISTS => '数据已经存在', - ReturnCode::AUTH_ERROR => '权限认证失败', - ReturnCode::OTHER_LOGIN => '别的终端登录', - ReturnCode::VERSION_INVALID => 'API版本非法', - ReturnCode::CURL_ERROR => 'CURL操作异常', - ReturnCode::RECORD_NOT_FOUND => '记录未找到', - ReturnCode::DELETE_FAILED => '删除失败', - ReturnCode::ADD_FAILED => '添加记录失败', - ReturnCode::UPDATE_FAILED => '更新记录失败', - ReturnCode::PARAM_INVALID => '数据类型非法', - ReturnCode::ACCESS_TOKEN_TIMEOUT => '身份令牌过期', - ReturnCode::SESSION_TIMEOUT => 'SESSION过期', - ReturnCode::UNKNOWN => '未知错误', - ReturnCode::EXCEPTION => '系统异常', - ); - - return view('', [ - 'errorInfo' => $errorInfo, - 'codeArr' => $codeArr - ]); - } - - public function login() { - return view(); - } - - /** - * 处理wiki登录 - * @throws \think\Exception - * @throws \think\exception\DbException - * @author zhaoxiang - */ - public function doLogin() { - $appId = $this->request->post('appId'); - $appSecret = $this->request->post('appSecret'); - - $appInfo = AdminApp::get(['app_id' => $appId, 'app_secret' => $appSecret]); - if (!empty($appInfo)) { - if ($appInfo->app_status) { - //保存用户信息和登录凭证 - session('app_info', json_encode($appInfo)); - $this->success('登录成功', url('/wiki/index')); - } else { - $this->error('当前应用已被封禁,请联系管理员'); - } - } else { - $this->error('AppId或AppSecret错误'); - } - } - - public function logout() { - session('app_info', null); - $this->success('退出成功', url('/wiki/login')); - } - -} diff --git a/application/wiki/view/index/calculation.html b/application/wiki/view/index/calculation.html deleted file mode 100644 index 9d9a0e5..0000000 --- a/application/wiki/view/index/calculation.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - {:config('apiadmin.APP_NAME')} - 算法说明 - - - -
-
-
-

{:config('apiadmin.APP_NAME')} - 算法说明

- - - -
- 特别说明: 此算法文档会根据业务发展需求发生变更,为了服务的稳定运行,请及时关注此文档! -
-
-
简介
-

当前算法主要服务于获取身份令牌(AccessToken)所进行的身份认证秘钥(signature)的计算。在请求高级接口的时候,系统会验证应用的合法性,也就是验证AccessToken。所以AccessToken是请求API的必要参数。

-

在请求获取AccessToken的接口时候,服务器会对用户合法性(signature)进行核验,具体的接口请求字段,请参看具体的接口文档。

-
一、获取app_id和app_secret
-

目前获取应用ID和应用秘钥是由系统管理员发放,如果你还没有请联系管理员。请注意:app_secret非常重要请妥善保管

-
二、准备加密对象,并且根据字段名降序排序
-
//排序好后应当是如下所示的数据
-{
-    "app_id":"服务器颁发的应用ID",
-    "app_secret":"服务器颁发的应用秘钥",   //请注意,此字段只是在计算加密串的时候在被加入,API请求请勿传递此字段值
-    "device_id":"设备唯一ID",
-    "rand_str":"随机字符串",
-    "timestamp":当前系统时间戳
-}
-
三、生成原始串
-

将上面的数据构建成HTTP查询字符串,如下所示:

-

app_id=服务器颁发的应用ID&app_secret=服务器颁发的应用秘钥&device_id=设备唯一ID&rand_str=随机字符串&timestamp=当前系统时间戳

-
四、计算秘钥
-

将第三步生成的字符串进行哈希计算(md5)获得最终身份认证秘钥。

-
-

© Powered By {:config('apiadmin.APP_NAME')} {:config('apiadmin.APP_VERSION')}

-

-
- - diff --git a/application/wiki/view/index/detail.html b/application/wiki/view/index/detail.html deleted file mode 100644 index bda647c..0000000 --- a/application/wiki/view/index/detail.html +++ /dev/null @@ -1,183 +0,0 @@ - - - - - {:config('apiadmin.APP_NAME')} - 在线接口列表 - - - - - - - -
-
-
-
-
-
- -
-
- {$groupInfo['name']} -
-

{$groupInfo['description']}

-
-
- 额外的细节 -
-
-
-
-
- {php}$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';{/php} -
接口访问地址:{$http_type}{$_SERVER['HTTP_HOST']}/api/{$hash}
-
-
- -
-
-
-

接口唯一标识:{$hash}{if condition="$detail['is_test'] == 1"}({$detail['api_class']}){/if}


-
- 接口说明 - {if condition="$detail['status'] eq 0 "} - 禁用 - {else /} - {if condition="$detail['is_test'] eq 1 "} - 测试 - {else /} - 启用 - {/if} - {/if} - {:config('apiadmin.APP_VERSION')} - - {switch name="detail['method']"} - {case value="1" break="1"}POST{/case} - {case value="2" break="1"}GET{/case} - {default /}不限 - {/switch} - -
-

{$detail['info']}

-
-
- -
-

公共请求参数

- - - - - - - - - - - - - - -
参数名字类型字段状态默认值其他说明
access-tokenString{$detail['access_token']==1?'复杂认证':'简易认证'}APP认证秘钥【请在Header头里面传递】
-

请求参数

- - - - - - {volist name="request" id="vo"} - - - - - - - - - {/volist} - -
参数名字类型是否必须默认值其他说明
{$vo['field_name']}{$dataType[$vo['data_type']]}{$vo['is_must']==1?'必填':'可选'}{$vo['default']}{$vo['range']}{$vo['info']}
-
-
-

公共返回参数

- - - - - - - - - - - - - - - - - - - - - -
返回字段类型说明
codeInteger返回码,详情请参阅错误码说明
msgString错误描述,当请求成功时可能为空
debugString调试字段,如果没有调试信息会没有此字段
-

返回参数

- - - - - - {volist name="response" id="vo"} - - - - - - {/volist} - -
返回字段类型说明
{$vo['show_name']}{$dataType[$vo['data_type']]}{$vo['info']}
-
-
-

-                
-
- 温馨提示: 此接口参数列表根据后台代码自动生成,如有疑问请咨询后端开发 -
-

© Powered By {:config('apiadmin.APP_NAME')} {:config('apiadmin.APP_VERSION')}

-

-
-
-
- - - diff --git a/application/wiki/view/index/error_code.html b/application/wiki/view/index/error_code.html deleted file mode 100644 index 45d8c28..0000000 --- a/application/wiki/view/index/error_code.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - {:config('apiadmin.APP_NAME')} - 错误码说明 - - - -
-
-
-

{:config('apiadmin.APP_NAME')} - 错误码说明

- - - - - - - - - - - {volist name="codeArr" id="vo"} - - - - - - - {/volist} - -
#英文标识错误码中文说明
- {$i} - - {$key} - - {$vo} - - {$errorInfo[$vo]} -
-

© Powered By {:config('apiadmin.APP_NAME')} {:config('apiadmin.APP_VERSION')}

-

-
- - diff --git a/application/wiki/view/index/index.html b/application/wiki/view/index/index.html deleted file mode 100644 index 92f7eba..0000000 --- a/application/wiki/view/index/index.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - {:config('apiadmin.APP_NAME')} - 在线接口文档 - - - -
-
-
-

{:config('apiadmin.APP_NAME')} - 接口文档

- - - - - - -
-
-
接口状态说明:
-

测试 系统将不过滤任何字段,也不进行AccessToken的认证,但在必要的情况下会进行UserToken的认证!

-

启用 系统将严格过滤请求字段,并且进行全部必要认证!

-

禁用 系统将拒绝所有请求,一般应用于危机处理!

-
-
- -

© Powered By {:config('apiadmin.APP_NAME')} {:config('apiadmin.APP_VERSION')}

-

-
- - diff --git a/application/wiki/view/index/login.html b/application/wiki/view/index/login.html deleted file mode 100644 index dfc2ba8..0000000 --- a/application/wiki/view/index/login.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - {:config('apiadmin.APP_NAME')} - 在线接口文档 - - - - - - - - - - - -
-
-

-
- 欢迎使用{:config('apiadmin.APP_NAME')}在线文档 -
-

-
-
-
-
- - -
-
-
-
- - -
-
-
提 交
-
-
-
-
- 如果您没有AppId和AppSecret,请联系服务供应商获取! -
-
-
- - diff --git a/application/wiki/view/index/login_res.html b/application/wiki/view/index/login_res.html deleted file mode 100644 index 7e0f098..0000000 --- a/application/wiki/view/index/login_res.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - ApiAdmin-微信登录 - - - -
-
-
- {if condition="$code eq 1 "} - - {else /} - - {/if} -
-
-

{$info}

-
-
- -
-
-
- - diff --git a/route/wikiRoute.php b/route/wikiRoute.php index e0ab0fd..8eb4c34 100644 --- a/route/wikiRoute.php +++ b/route/wikiRoute.php @@ -8,9 +8,24 @@ use think\facade\Route; Route::group('wiki', function() { - Route::rule( - 'Api/errorCode', 'wiki/Api/errorCode', 'get' - ); + Route::group('Api', [ + 'errorCode' => [ + 'wiki/Api/errorCode', + ['method' => 'get'] + ], + 'groupList' => [ + 'wiki/Api/groupList', + ['method' => 'get'] + ], + 'login' => [ + 'wiki/Api/login', + ['method' => 'post'] + ], + 'detail' => [ + 'wiki/Api/detail', + ['method' => 'get'] + ] + ])->middleware(['WikiAuth']); //MISS路由定义 Route::miss('admin/Miss/index');