PHP开发高可用高安全App后端,php高安全app后端
- 安全性
- 授权码sign算法
- 登录场景access_user_token算法
- token唯一性支持
- API一次性请求支持
- 高可用
- Restful API
- web登录和APP登录异同处
- 阿里大于短信验证解决客户端APP复杂登录场景
- API接口版本解决方案
- APP本地时间和服务器时间一致解决方案
- 不可预知的API内部异常解决方案
- APP版本升级方案
- 利用七牛云解决图片处理基础服务能力
- 基础类库的封装
- PHP设计模式的穿透
- 部分模块提供多种解决方案最后选择最优的方案
- PHP和ajax的异步数据交互
后台
- h-ui admin 模板
- uploadify 上传文件
知识点
restful api数据结构格式
3. HTTP状态码使用TK自带的json实现
3. status 业务状态码
4. message 提示信息
5. data 数据层
通用化API接口数据封装
function show($status, $message, $data=[], $httpCode=200) {
$data = [
'status' => $status,
'message' => $message,
'data' => $data,
];
return json($data, $httpCode);
}
不可预知的内部异常api数据输出解决方案
config配置exception_handle填写异常类路径
class ApiHandleException extends Handle {
/**
* http 状态码
* @var int
*/
public $httpCode = 500;
public function render(\Exception $e) {
// 还原正常报错,上线后为flase(服务端开发)
if(config('app_debug') == true) {
return parent::render($e);
}
if ($e instanceof ApiException) {
$this->httpCode = $e->httpCode;
}
return show(0, $e->getMessage(), [], $this->httpCode);
}
}
class ApiException extends Exception {
public $message = '';
public $httpCode = 500;
public $code = 0;
/**
* @param string $message
* @param int $httpCode
* @param int $code
*/
public function __construct($message = '', $httpCode = 0, $code = 0) {
$this->httpCode = $httpCode;
$this->message = $message;
$this->code = $code;
}
}
APP-API数据安全
解决方式就是各种的加密:MD5 AES(对称加密) RSA(非对称,效率较低)
sign (有效时间,唯一性)
/**
* 生成每次请求的sign
* @param array $data
* @return string
*/
public static function setSign($data = []) {
// 1 按字段排序
ksort($data);
// 2拼接字符串数据 &
$string = http_build_query($data);
// 3通过aes来加密
$string = (new Aes())->encrypt($string);
return $string;
}
/**
* 检查sign是否正常
* @param array $data
* @param $data
* @return boolen
*/
public static function checkSignPass($data) {
$str = (new Aes())->decrypt($data['sign']);
if(empty($str)) {
return false;
}
// diid=xx&app_type=3
parse_str($str, $arr);
if(!is_array($arr) || empty($arr['did'])
|| $arr['did'] != $data['did']
) {
return false;
}
// 有效时间:时间间隔不能超过60s
if(!config('app_debug')) {
if ((time() - ceil($arr['time'] / 1000)) > config('app.app_sign_time')) {
return false;
}
//echo Cache::get($data['sign']);exit;
// 唯一性判定
if (Cache::get($data['sign'])) {
return false;
}
}
return true;
}
/**
* 检查每次app请求的数据是否合法
*/
public function checkRequestAuth() {
// 首先需要获取headers
$headers = request()->header();
// todo
// sign 加密需要 客户端工程师 , 解密:服务端工程师
// 1 headers body 仿照sign 做参数的加解密
// 2
// 3
// 基础参数校验
if(empty($headers['sign'])) {
throw new ApiException('sign不存在', 400);
}
if(!in_array($headers['app_type'], config('app.apptypes'))) {
throw new ApiException('app_type不合法', 400);
}
// 需要sign
if(!IAuth::checkSignPass($headers)) {
throw new ApiException('授权码sign失败', 401);
}
Cache::set($headers['sign'], 1, config('app.app_sign_cache_time'));
// 1、文件 2、mysql 3、redis
$this->headers = $headers;
}
API接口数据安全解决方案之sign有效时间处理
解决:获取服务端时间,客户端拿到服务端正确时间进行对比。
API接口文档编写(API入参,出参的格式)
- API接口地址
- 请求方式
- 入参格式
- 出参格式
- http code
PHP之友评论