api管理系统php源码(Api国内PHP开源接口框架)

上一章起了个头,这一章咱们亲身做一下这个API的基础结构。我们给它叫做“老赵API系统”。首先,我们要做的这个API系统是私有的,不开源的,不分发给其它人一起用(当然你非要大力推广,也随便你)。其次,我故意遗漏了一个小小的点子,这个点子我自己用,我也

上一章起了个头,这一章咱们亲身做一下这个API的基础结构。

我们给它叫做“老赵API系统”。

首先,我们要做的这个API系统是私有的,不开源的,不分发给其它人一起用(当然你非要大力推广,也随便你)。

其次,我故意遗漏了一个小小的点子,这个点子我自己用,我也是怕我这个办法泄露后会有安全问题。

就当是抛砖引玉吧。

先说要注意的几点:

0、不要使用默认首页

1、不使用SESSION和COOKIE

2、每次访问都需要验证用户名密码

3、任何单个文件都不允许能正常运行

4、任何单个文件都不允许能单独实现任何功能

5、未验证成功身份时不输出任何错误提示

相信很多高人一看这几条就会知道我要怎么做。也会有一部分人会嗤之以鼻说太初级。

管他呢,反正这是我自己摸索出来的,就是黑客黑我也只能在操作系统方面下手,在我这套系统里他永远不可能有成功的访问请求。

下面详细说:

0、不要使用默认首页。

如果你的环境里首页设置了很多,比如index.php,index.html,default.html,default.php之类的,那么你API的接口文件一定不能用这些,比如你可以用iLaoZhao_XX_api.php,这谁猜得到?

1、不使用SESSION和COOKIE。

COOKIE是用明文存在于用户端的,很容易查看和修改,这个大家都清楚。而PHP的SESSION也依赖于COOKIE来存储一个SESSION_ID。并且我们的API要每次访问就返回一次数据,很多访问方法并不会存储COOKIE,这会导致SESSION失效。

2、每次访问都验证用户名密码。

现在流行那个啥叫Token的方式,我懒得研究,倒不如每次都验证用户名和密码,这样等密码泄露后只要我改一个密码,他那边立马就不能用了。都不用等他那边信息过期。当然我们不能明文传递这些东西,需要做一定加密处理。

3、任何单个文件都不允许能正常运行。

资源文件夹不能有任何可执行文件。并且尽量多分几个文件,所有的文件相互依赖,并且把它们互相组织起来的文件又是另一个单独文件,这样即便别人知道了我们的文件路径和文件名,当访问这个文件时,也无法正常运行。

4、任何单个文件都不允许能单独实现任何功能。

某个文件要实现功能,必须依赖其它文件内的函数或类,并且当前文件不能知道这些函数和类具体在哪个文件里实现的。这样即便这个文件的源代码泄露,对方也不知道里面的依赖关系,不会连累到其它文件。

5、未验证成功身份时不输出任何错误提示。

在用户名密码出错时,系统不要输出任何有用的信息,或者输出一个假的404信息,这样别人在试探我们的系统时,根本不知道是哪一步出错了,而我们的客户端可以根据里面的暗语来判断状态。

我做一个小例子来说明一下,这个小例子只是抛砖引玉,并不是我最终的代码样子。

文件树结构:

老赵API文件树结构

根目录下只有一个文件夹,整个API系统都通过一个接口文件”DaYeLaiWanA.php”来调用。

怎么样,不知道文件结构的人根本猜不对你有哪些文件,也就不能访问任何文件。

下面的代码没有使用太先进的语法,比如类和对象啊命名空间啊啥的,新版本PHP添了好多特性,但我比较倾向于不去使用它们,我要尽量的让代码对环境没有要求,在尽可能多的版本环境下都能运行。

毕竟我们要的是安全,而不是让所有人能读懂我们的代码。

我们要尽可能的不使用教科书上的通用的写法,尽可能搞一套自己的写法。

下面是DaYeLaiWanA.php的代码:

<?php
//接口文件,单独调用这个文件没任何作用,参数必须得对,差一个字母这个文件都运行不出个毛线来。
//而参数是你自己定的,可随意加密修改。

//当然你还可以把这个路径也放到变量里,然后藏起来。
include \"./iLaoZhao_funs/postget.php\"; //没有依赖,但也不实现任何具体功能
include \"./iLaoZhao_funs/login.php\"; //依赖pdo,dbfuns,postget和接口文件
include \"./iLaoZhao_funs/curl.php\"; //没有依赖,但也不实现任何具体功能
include \"./iLaoZhao_funs/dbfuns.php\"; //依赖pdo和接口文件
//上面这些文件里涉及到安全的功能都有依赖,并且他们不知道要用的函数在哪
//全靠这个接口文件把它们组合到一起
//并且上面的函数里也会用到接口文件的函数(就是下面那个)
//这些因素缺一不可,只能由接口文件来整合他们
//上面这些文件和其它的API文件,都无法单独运行。不是缺这就是缺那。

//下面这俩函数是故意没单独放文件里的,为的就是其它文件缺少这个接口文件时在调用这个函数时会出错。
function output2Die($msg, $code = -1, $data = \'\'){
$dieMsg[\'code\'] = $code;
$dieMsg[\'msg\'] = $msg;
$dieMsg[\'data\'] = $data;
echo json_encode($dieMsg);
die();
}

function isPhone($phonenumber)
{
return preg_match(\"/^1[3-9]d{9}$/\", $phonenumber);
}

$area = POST(\"area\");//要使用的API种类
$class = POST(\"class\");//要使用的API小分类
$fun = POST(\"fun\");//要使用的API功能

//清理POST
unset($_POST[\'area\']);
unset($_POST[\'class\']);
unset($_POST[\'fun\']);

if ($class !== FALSE && $fun !== FALSE){

if ($area == false){
$area = \"public\";
}

//生成API文件全名,这里没加密,你可以自己变动这里。
$incFile = dirname(__FILE__).\"/{$area}/{$class}/{$fun}.php\";

if (file_exists($incFile)){ //检查API文件是否存在,其实不检查也行。
include \"./config/pdodb.php\"; //创建数据库连接,依赖接口文件
include $incFile;//将单独的API文件导入进来
}else{
//我因为调试的原因,显示了错误信息,要求高的可以去掉。
output2Die(\"无效的请求\", -1);
}
}else{
output2Die(\"无效的请求\", -2);
}

文件我写了注释,方便大家看,实际在使用时不能有这些注释,这些注释只能方便别人破解我们的系统,并且这个接口文件尽可能进行代码混淆加密。

然后是一个获得当前用户信息的小例子API,这个API文件存在了
/iLaoZhao_api/public/login/usrMsg.php里面。在调用时大概URL是这样:

https://你的域名/iLaoZhao_api/DaYeLaiWanA.php

POST数据为:{
key:\"用户名密码时间加密字符串运算后的结果\",
class:\"login\",
fun:\"usrMsg\",
userName:\"该用户的用户名\"
}

API代码内容usrMsg.php为:

<?php
//示例文件,得到当前用户的所有信息
//文件依赖:接口文件、数据库连接文件、dbfuns文件、login文件
//单独访问这个文件根本不能运行
//依赖关系完全靠接口文件处理

//这个API读取post参数中的userName
checkUserNamePassWord(); //检查用户名密码,不对真接就终止运行了,对了的话就可以运行下面的代码
$dbArr[\'userName\'] = POST(\"userName\");
if($dbArr[\'userName\'] !== false){ //这一步没必要,能验证过上面那个函数,这个参数肯定存在,但我就是写了,就是玩儿
//一定要用PDO的绑定功能访问数据库,这种方式能避免SQL注入。
$sql = \"select * from tb_users where users_userName = :userName\";
$rec = db_query($sql,$dbArr);
if($rec[\'count\'] > 0){
output2Die(\"成功。\",1,$rec);
}else{
output2Die(\"找不到该用户。\",-1); //要求高的,不要输出错误信息。
}
}
output2Die(\"失败\",-2); //要求高的,不要输出错误信息。

这里面的checkUserNamePassWord()函数(在iLaoZhao_funs文件夹内的login.php文件里)也比较关键:

<?php
/**
* 判断用户名密码的函数
此函数不允许返回东西
调用的时候直接调用
用户正常自然没反应
用户不正常,这个函数直接结束程序运行。
*/
function checkUserNamePassWord(){
$keyStr = \"这里是加密字符串,这个串只有你自己知道是什么。\";

$key = POST(\"key\"); //这个key是客户端把用户名密码时间加密字符串运算后的结果

//用当前日期当第二密钥,这个作用是每天的密钥都不一样。
//即便被拦截了,也算不出规律来,当然源码泄露了就不行了。
//不能太精确,因为客户端与服务器端的时间不可能完全一样。
$keyStr_Today = date(\'Ymd\',time());

//访问数据库,一定要用PDO的这个参数方式。
//这个方式在代入数据与直接写在SQL语句里不一样。
//sql注入在这种使用方式下完全不会生效。
$sqlPar[\'username\'] = POST(\"userName\"); //这个没加密的必要,这个在输入框里就能看到,而且也会在很多地方显示。
if($sqlPar[\'username\'] === false || $key === false){
//非法调用
}

//不要在sql里直接比对用户名密码
//而且传过来的数据也没有密码
//要取出该用户的记录,然后计算后与传过来的加密身份信息对比
$sql = \"select * from tb_users where userName=:username\"; //你可以在这limit 1
$rec = db_query($sql, $sqlPar);
if($rec[\'count\'] > 0){

$keyInDB = md5(md5($keyStr).md5($rec[\'rows\'][0][\'userName\']).md5($keyStr_Today).md5($rec[\'rows\'][0][\'passWord\']));
//上面这句是加密方式,把加密字符串、用户名、当前日期、密码的MD5连接起来并再计算一次MD5
//当然你还可以再加点别的东西,比如字符串反转,以及其它变量之类的。
//上面这句计算出来的和$key中的一样时,说明密码是对的。
if($key == $keyInDB){
//用户名密码对
//此时我们啥也不做
//或者你想设置某些变量也行
}else{
//否则
die(); //结束程序运行,
}
}
}

代码里都有注释,应该能看清楚。而且还有其它的自定义函数我就不放代码了。

这样我们在扩充API时只需要在对应路径下写PHP代码文件就行,而且很多函数可以直接使用,不用include任何文件。

而且这个系统内所有的文件在单独访问时都会出错(可以设置PHP不显示错误信息),而接口文件在参数不正确的情况下也不会有什么具体运行结果。

也没有默认的首页文档可以访问。

文件路径和文件名都没规律,在网上都查不到参考。

那么想黑掉这套API只有两个办法:

0、黑掉服务器操作系统,再从文件系统入手。

1、破解客户端代码或者拦截访问数据,找到访问规律。

这两点暂时无能为力解决。

**边写文档边写代码,头有点乱,可能有遗漏的东西,不知道大家能不能看懂。

**此API系统还有很多地方可以进一步加密处理,但我个人感觉没必要了。已经够可以了。

**此代码没有使用太先进的语法,比如类啊命名空间啊啥的,新版本PHP添了好多特性,但我比较倾向于不去使用它们,我要尽量的让代码对环境没有要求,在尽可能多的版本环境下都能运行。

毕竟我们要的是安全,而不是让所有人能读懂我们的代码。

有啥忘了的以后再补充吧。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/16115.html

(0)
nan
上一篇 2021-08-21
下一篇 2021-08-21

相关推荐

  • 自学plc编程先学什么(plc如何编程)

    PLC模块1.建议先学习电气元件的基础知识。可从理论知识入手,如PLC人机界面的概念、开关、继电器、接触器、热继电器、电磁阀等理论知识入手,对该行业使用的基本元件有一个基本的认识。首先了解它,你不一定懂,但是在后面学习的过程中,有了这个知识点,你就会恍然大悟,这个我早就学习过。三菱PLC2.建议…

    2021-10-22
    0
  • 手机软件用什么语言开发(开发手机应用用什么语言)

    手机软件用什么语言开发,开发手机应用用什么语言内容导航:智能手机软件都是用什么编写的智能手机的软件通常用什么语言编写的请问现在开发手机软件靠什么赚钱开发app用什么语言一、智能手机软件都是用什么编写的智能手机

    2022-04-25
    0
  • 怎么用Python编写一个进程勾选器

    要编写一个进程勾选器(也就是监视和选择进程)的Python程序,可以使用psutil库来获取系统当前运行的进程信息,并使用tkinter库来创建一个图形化界面来展示进程信息和进行选择操作。以下是一个简单的示例代码,实现了一个基础的进程勾选器功能:import psutilimport tkinter as tkdef update_process_list():process_list.de

    2024-03-05
    0
  • Scala如何与Java集成

    Scala与Java集成非常方便,因为Scala可以直接调用Java代码,并且可以在Scala中使用Java类库。以下是一些方法来实现Scala与Java集成:调用Java代码:Scala可以直接调用Java代码,并且可以访问Java类的方法和字段。只需要将Java类导入到Scala中,然后就可以调用Java类的方法。使用Java类库:Scala可以使用Java类库,例如Java集合框架、IO操作

    2024-04-12
    0
  • 「有网但是网页全打不开怎么回事」有网但是网页都打不开

    有网但是网页全打不开怎么回事,有网但是网页都打不开 内容导航: 为什么网络显示正常连接但是所有网页打不开 手机上面显示的也有网可还是打不开网页为什么 电脑宽带已经连接但是网页打不开…

    2022-05-18
    0
  • opencv怎么实现图片缩略

    在OpenCV中,可以使用cv2.resize()函数来实现图片的缩略。该函数可以将图像缩放到指定的大小。以下是一个示例代码,展示了如何将图像缩小到指定的宽度和高度:import cv2# 读取图像image = cv2.imread('image.jpg')# 缩放图像width = 200 # 指定缩略图的宽度height = 200 # 指定缩略图的高度r

    2024-02-02
    0

发表回复

登录后才能评论