Browse Source

跨站调用功能完善

tags/6.2.7
tianya 1 year ago
parent
commit
e223d3b6fa
7 changed files with 239 additions and 20 deletions
  1. +105
    -4
      src/admin/catalog_do.php
  2. +69
    -0
      src/admin/templets/catalog_main.htm
  3. +2
    -2
      src/system/archive/listview.class.php
  4. +26
    -0
      src/system/archive/sglistview.class.php
  5. +33
    -10
      src/system/libraries/jsonq/JsonQueriable.php
  6. +2
    -2
      src/system/taglib/jsonq.lib.php
  7. +2
    -2
      src/system/typelink/typeunit.class.admin.php

+ 105
- 4
src/admin/catalog_do.php View File

@@ -270,10 +270,111 @@ else if ($dopost == 'viewAPI') {
require_once(DEDEINC.'/typelink/typelink.class.php');
$typeid = isset($typeid) ? intval($typeid) : 0;
$tl = new TypeLink($typeid);
$phpCode = '<?php
$typeid = '.$typeid.';
$row = 10;
$timestamp = time();
$sign = sha1($typeid.$timestamp.$tl->TypeInfos['apikey'].'1'.'10');
$u = "tid={$typeid}&mod=1&timestamp={$timestamp}&PageNo=1&PageSize=10&sign={$sign}";
header('HTTP/1.1 301 Moved Permanently');
header("Location:../apps/list.php?{$u}");
$apikey = \''.$tl->TypeInfos['apikey'].'\';
$sign = md5($typeid.$timestamp.$apikey.\'1\'.$row);
$durl = "'.$cfg_basehost.'/apps/list.php?tid={$typeid}&mod=1&timestamp={$timestamp}&PageNo=1&PageSize={$row}&sign={$sign}";
$data = json_decode(file_get_contents($durl),true);
if ($data[\'code\'] === 0) {
var_dump($data);
}
?>';
$gocode = 'package main

import (
"crypto/md5"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"time"
)

func main() {
typeid := '.$typeid.'
row := 10
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
apikey := "'.$tl->TypeInfos['apikey'].'"
sign := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%d%s%s%d%d", typeid, timestamp, apikey, 1, row))))
durl := fmt.Sprintf("'.$cfg_basehost.'/apps/list.php?tid=%d&mod=1&timestamp=%s&PageNo=1&PageSize=%d&sign=%s", typeid, timestamp, row, sign)
resp, err := http.Get(durl)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
var data map[string]interface{}
if err := json.Unmarshal(body, &data); err != nil {
fmt.Println(err)
return
}
if data["code"].(float64) == 0 {
fmt.Printf("%+v", data)
}
}';
$pythoncode = 'import hashlib
import json
import time
import urllib.request

typeid = '.$typeid.'
row = 10
timestamp = int(time.time())
apikey = \''.$tl->TypeInfos['apikey'].'\'
sign = hashlib.md5((str(typeid) + str(timestamp) + apikey + \'1\' + str(row)).encode()).hexdigest()
durl = f"'.$cfg_basehost.'/apps/list.php?tid={typeid}&mod=1&timestamp={timestamp}&PageNo=1&PageSize={row}&sign={sign}"
with urllib.request.urlopen(durl) as url:
data = json.loads(url.read().decode())
if data[\'code\'] == 0:
print(data)
';
$jscode = 'const crypto = require(\'crypto\');
const http = require(\'http\');

const typeid = '.$typeid.';
const row = 10;
const timestamp = Math.floor(Date.now() / 1000);
const apikey = \''.$tl->TypeInfos['apikey'].'\';
const sign = crypto.createHash(\'md5\').update(typeid.toString() + timestamp.toString() + apikey + \'1\' + row.toString()).digest(\'hex\');
const durl = `'.$cfg_basehost.'/apps/list.php?tid=${typeid}&mod=1&timestamp=${timestamp}&PageNo=1&PageSize=${row}&sign=${sign}`
http.get(durl, (res) => {
let data = \'\';
res.on(\'data\', (chunk) => {
data += chunk;
});
res.on(\'end\', () => {
console.log(data);
const result = JSON.parse(data);
if (result.code === 0) {
console.log(result);
}
});
}).on(\'error\', (err) => {
console.log(err);
});';
$tagcode = '<ul>
{dede:jsonq url="'.$cfg_basehost.'" row="10" typeid='.$typeid.' apikey="'.$tl->TypeInfos['apikey'].'"}
<li><a href="[field:arcurl/]">[field:title/]</a></li>
{/dede:jsonq}
</ul>';
echo json_encode(array(
"code"=>0,
"data"=>array(
"phpcode"=>htmlspecialchars($phpCode),
"gocode"=>htmlspecialchars($gocode),
"pythoncode"=>htmlspecialchars($pythoncode),
"jscode"=>htmlspecialchars($jscode),
"tagcode"=>htmlspecialchars($tagcode),
)
));
}
?>

+ 69
- 0
src/admin/templets/catalog_main.htm View File

@@ -8,6 +8,8 @@
<link rel="stylesheet" href="../static/web/css/bootstrap.min.css">
<link rel="stylesheet" href="../static/web/css/admin.css">
<style>.admin-td{border-bottom:1px solid #dee2e6!important}</style>
<script src="../static/web/js/jquery.min.js"></script>
<script src="../static/web/js/bootstrap.min.js"></script>
<script src="../static/web/js/webajax.js"></script>
<script src="js/global.js"></script>
</head>
@@ -46,6 +48,59 @@
</tr>
</table>
</form>
<div id="mdlViewAPI" class="modal fade" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">跨站调用</h5>
<button type="button" class="update-close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times"></i></button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<span>
本功能主要用于移动客户端或第三方系统调用栏目数据进行展现。
</span>
</div>
<div class="form-group">
<label for="iptAPICode">代码调用</label>
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<button class="nav-link active" id="nav-php-tab" data-toggle="tab" data-target="#nav-php" type="button" role="tab" aria-controls="nav-php" aria-selected="true">PHP</button>
<button class="nav-link" id="nav-js-tab" data-toggle="tab" data-target="#nav-js" type="button" role="tab" aria-controls="nav-js" aria-selected="true">Javasctipt</button>
<button class="nav-link" id="nav-go-tab" data-toggle="tab" data-target="#nav-go" type="button" role="tab" aria-controls="nav-go" aria-selected="false">Go</button>
<button class="nav-link" id="nav-python-tab" data-toggle="tab" data-target="#nav-python" type="button" role="tab" aria-controls="nav-python" aria-selected="false">Python3</button>
</div>
</nav>
<div class="tab-content py-3" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-php" role="tabpanel" aria-labelledby="nav-php-tab">
<pre><code id="codephp"></code></pre></div>
<div class="tab-pane fade" id="nav-js" role="tabpanel" aria-labelledby="nav-js-tab">
<pre><code id="codejs"></code></pre>
</div>
<div class="tab-pane fade" id="nav-go" role="tabpanel" aria-labelledby="nav-go-tab">
<pre><code id="codego"></code></pre>
</div>
<div class="tab-pane fade" id="nav-python" role="tabpanel" aria-labelledby="nav-python-tab">
<pre><code id="codepython"></code></pre>
</div>
</div>
</div>
<div class="form-group">
<label for="iptAPITag">标签调用</label>
<pre><code id="codetag"></code></pre>
</div>
</form>
</div>
<div class="modal-footer">
<div class="btnStep">
<button id="btnGoStep4" type="button" class="btn btn-success">我知道了</button>
</div>
</div>
</div>
</div>
</div>
<script>
function LoadSuns(ctid, tid) {
if ($DE(ctid).innerHTML.length < 10) {
@@ -66,6 +121,20 @@
$DE(objname).style.display = "none";
}
}
function showAPI(tid) {
fetch('catalog_do.php?dopost=viewAPI&typeid=' + tid).then(resp => resp.text()).then((d) => {
let data = JSON.parse(d);
if (data.code == 0) {
$("#codephp").html(data.data.phpcode);
$("#codego").html(data.data.gocode);
$("#codepython").html(data.data.pythoncode);
$("#codejs").html(data.data.jscode);
$("#codetag").html(data.data.tagcode);
$("#mdlViewAPI").modal('show');
}
});
}
</script>
</body>
</html>

+ 2
- 2
src/system/archive/listview.class.php View File

@@ -98,8 +98,8 @@ class ListView
));
exit;
}
//验签算法 sha1(typeid+timestamp+apikey+PageNo+PageSize)
$sign = sha1($this->TypeID.$GLOBALS['timestamp'].$this->Fields['apikey'].$GLOBALS['PageNo'].$GLOBALS['PageSize']);
//验签算法 md5(typeid+timestamp+apikey+PageNo+PageSize)
$sign = md5($this->TypeID.$GLOBALS['timestamp'].$this->Fields['apikey'].$GLOBALS['PageNo'].$GLOBALS['PageSize']);
if ($sign !== $GLOBALS['sign']) {
echo json_encode(array(
"code" => -1,


+ 26
- 0
src/system/archive/sglistview.class.php View File

@@ -78,6 +78,32 @@ class SgListView
//设置一些全局参数的值
foreach ($GLOBALS['PubFields'] as $k => $v) $this->Fields[$k] = $v;
$this->Fields['rsslink'] = $GLOBALS['cfg_cmsurl']."/static/rss/".$this->TypeID.".xml";
//API相关逻辑处理
if ($this->mod == 1 && empty($this->Fields['apikey'])) {
echo json_encode(array(
"code" => -1,
"msg" => "api key is empty",
));
exit;
}
if($this->mod == 1){
if (empty($GLOBALS['sign'])) {
echo json_encode(array(
"code" => -1,
"msg" => "sign is empty",
));
exit;
}
//验签算法 md5(typeid+timestamp+apikey+PageNo+PageSize)
$sign = md5($this->TypeID.$GLOBALS['timestamp'].$this->Fields['apikey'].$GLOBALS['PageNo'].$GLOBALS['PageSize']);
if ($sign !== $GLOBALS['sign']) {
echo json_encode(array(
"code" => -1,
"msg" => "sign check failed",
));
exit;
}
}
//设置环境变量
SetSysEnv($this->TypeID, $this->Fields['typename'], 0, '', 'list');
$this->Fields['typeid'] = $this->TypeID;


+ 33
- 10
src/system/libraries/jsonq/JsonQueriable.php View File

@@ -88,7 +88,11 @@ trait JsonQueriable
{
if (!is_null($file)) {
if (is_string($file)) {
$this->_map = $this->getDataFromFile($file);
if (preg_match("#^http#", $file)) {
$this->_map = $this->getDataFromUrl($file);
} else {
$this->_map = $this->getDataFromFile($file);
}
$this->_baseContents = $this->_map;
return true;
}
@@ -242,20 +246,39 @@ trait JsonQueriable
* Read JSON data from file
*
* @param string $file
* @param string $type
* @return bool|string|array
* @throws FileNotFoundException
* @throws InvalidJsonException
*/
protected function getDataFromFile($file, $type = 'application/json')
protected function getDataFromFile($file)
{
$data = file_get_contents($file);
$json = $this->isJson($data, true);
if (!$json) {
throw new InvalidJsonException();
}
return $json;
}
/**
* Get JSON data from url
*
* @param string $url
* @return bool|string|array
* @throws FileNotFoundException
* @throws InvalidJsonException
*/
protected function getDataFromUrl($url)
{
$opts = [
'http' => [
'header' => 'Content-Type: '.$type.'; charset=utf-8',
],
];
$context = stream_context_create($opts);
$data = file_get_contents($file, 0, $context);
$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5);
curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 10 );
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36');
$data = curl_exec($curl_handle);
curl_close($curl_handle);
$json = $this->isJson($data, true);
if (!$json) {
throw new InvalidJsonException();


+ 2
- 2
src/system/taglib/jsonq.lib.php View File

@@ -22,10 +22,10 @@ function lib_jsonq(&$ctag, &$refObj)
}
if ($typeid > 0) {
$timestamp = time();
$sign = sha1($typeid.$timestamp.$apikey.'1'.'10');
$sign = md5($typeid.$timestamp.$apikey.'1'.$row);
$u = "tid={$typeid}&mod=1&timestamp={$timestamp}&PageNo=1&PageSize={$row}&sign={$sign}";
$url = $url."/apps/list.php?{$u}";
$path = "$.lists";
$path = "lists";
}
$key = md5($url);
try {


+ 2
- 2
src/system/typelink/typeunit.class.admin.php View File

@@ -115,7 +115,7 @@ class TypeUnit
echo "</td>";
echo "<td align='right'><a href='{$GLOBALS['cfg_phpurl']}/list.php?tid={$id}' target='_blank' title='预览' class='btn btn-light btn-sm'><i class='fa fa-eye'></i></a>";
$apidisabled = $row->apienabled == 1? '' : ' disabled';
echo "<a href='catalog_do.php?dopost=viewAPI&typeid={$id}' target='_blank' title='接口' class='btn btn-light btn-sm{$apidisabled}'><i class='fa fa-bolt'></i></a>";
echo "<a href='javascript:showAPI({$id})' title='跨站' class='btn btn-light btn-sm{$apidisabled}'><i class='fa fa-bolt'></i></a>";
echo "<a href='catalog_do.php?cid={$id}&dopost=listArchives' title='文档' class='btn btn-light btn-sm'><i class='fa fa-file-text'></i></a>";
echo "<a href='catalog_add.php?id={$id}' title='添加' class='btn btn-light btn-sm'><i class='fa fa-plus-circle'></i></a>";
echo "<a href='catalog_edit.php?id={$id}' title='修改' class='btn btn-light btn-sm'><i class='fa fa-pencil-square'></i></a>";
@@ -200,7 +200,7 @@ class TypeUnit
echo "</td>";
echo "<td align='right'><a href='{$GLOBALS['cfg_phpurl']}/list.php?tid={$id}' target='_blank' title='预览' class='btn btn-light btn-sm'><i class='fa fa-eye'></i></a>";
$apidisabled = $row->apienabled == 1? '' : ' disabled';
echo "<a href='catalog_do.php?dopost=viewAPI&typeid={$id}' target='_blank' title='接口' class='btn btn-light btn-sm{$apidisabled}'><i class='fa fa-bolt'></i></a>";
echo "<a href='javascript:showAPI({$id})' title='跨站' class='btn btn-light btn-sm{$apidisabled}'><i class='fa fa-bolt'></i></a>";
echo "<a href='catalog_do.php?cid={$id}&dopost=listArchives' title='文档' class='btn btn-light btn-sm'><i class='fa fa-file-text'></i></a>";
echo "<a href='catalog_add.php?id={$id}' title='添加' class='btn btn-light btn-sm'><i class='fa fa-plus-circle'></i></a>";
echo "<a href='catalog_edit.php?id={$id}' title='修改' class='btn btn-light btn-sm'><i class='fa fa-pencil-square'></i></a>";


Loading…
Cancel
Save