日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php 接口安全解决方案,php接口数据安全解决方案(一)

發布時間:2025/3/11 php 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php 接口安全解决方案,php接口数据安全解决方案(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

目的:

1.實現前后端代碼分離,分布式部署

2.利用token替代session實現狀態保持,token是有時效性的滿足退出登錄,token存入redis可以解決不同服務器之間session不同步的問題,滿足分布式部署

3.利用sign,前端按照約定的方式組合加密生成字符串來校驗用戶傳遞的參數跟后端接收的參數是否一直,保障接口數據傳遞的安全

4.利用nonce,timestamp來保障每次請求的生成sign不一致,并將sign與nonce組合存入redis,來防止api接口重放

目錄介紹

├── Core

│?? ├── Common.php(常用的公用方法)

│?? ├── Controller.php (控制器基類)

│?? └── RedisService.php (redis操作類)

├── config.php (redis以及是否開啟關閉接口校驗的配置項)

├── login.php (登錄獲取token入口)

└── user.php(獲取用戶信息,執行整個接口校驗流程)

登錄鑒權圖

接口請求安全性校驗整體流程圖

代碼展示

common.php

namespace Core;

/**

* @desc 公用方法

* Class Common

*/

class Common{

/**

* @desc 輸出json數據

* @param $data

*/

public static function outJson($code,$msg,$data=null){

$outData = [

'code'=>$code,

'msg'=>$msg,

];

if(!empty($data)){

$outData['data'] = $data;

}

echo json_encode($outData);

die();

}

/***

* @desc 創建token

* @param $uid

*/

public static function createToken($uid){

$time = time();

$rand = mt_rand(100,999);

$token = md5($time.$rand.'jwt-token'.$uid);

return $token;

}

/**

* @desc 獲取配置信息

* @param $type 配置信息的類型,為空獲取所有配置信息

*/

public static function getConfig($type=''){

$config = include "./config.php";

if(empty($type)){

return $config;

}else{

if(isset($config[$type])){

return $config[$type];

}

return [];

}

}

}

RedisService.php

namespace Core;

/*

*@desc redis類操作文件

**/

class RedisService{

private $redis;

protected $host;

protected $port;

protected $auth;

protected $dbId=0;

static private $_instance;

public $error;

/*

*@desc 私有化構造函數防止直接實例化

**/

private function __construct($config){

$this->redis = new \Redis();

$this->port = $config['port'] ? $config['port'] : 6379;

$this->host = $config['host'];

if(isset($config['db_id'])){

$this->dbId = $config['db_id'];

$this->redis->connect($this->host, $this->port);

}

if(isset($config['auth']))

{

$this->redis->auth($config['auth']);

$this->auth = $config['auth'];

}

$this->redis->select($this->dbId);

}

/**

*@desc 得到實例化的對象

***/

public static function getInstance($config){

if(!self::$_instance instanceof self) {

self::$_instance = new self($config);

}

return self::$_instance;

}

/**

*@desc 防止克隆

**/

private function __clone(){}

/*

*@desc 設置字符串類型的值,以及失效時間

**/

public function set($key,$value=0,$timeout=0){

if(empty($value)){

$this->error = "設置鍵值不能夠為空哦~";

return $this->error;

}

$res = $this->redis->set($key,$value);

if($timeout){

$this->redis->expire($key,$timeout);

}

return $res;

}

/**

*@desc 獲取字符串類型的值

**/

public function get($key){

return $this->redis->get($key);

}

}

Controller.php

namespace Core;

use Core\Common;

use Core\RedisService;

/***

* @desc 控制器基類

* Class Controller

* @package Core

*/

class Controller{

//接口中的token

public $token;

public $mid;

public $redis;

public $_config;

public $sign;

public $nonce;

/**

* @desc 初始化處理

* 1.獲取配置文件

* 2.獲取redis對象

* 3.token校驗

* 4.校驗api的合法性check_api為true校驗,為false不用校驗

* 5.sign簽名驗證

* 6.校驗nonce,預防接口重放

*/

public function __construct()

{

//1.獲取配置文件

$this->_config = Common::getConfig();

//2.獲取redis對象

$redisConfig = $this->_config['redis'];

$this->redis = RedisService::getInstance($redisConfig);

//3.token校驗

$this->checkToken();

//4.校驗api的合法性check_api為true校驗,為false不用校驗

if($this->_config['checkApi']){

// 5. sign簽名驗證

$this->checkSign();

//6.校驗nonce,預防接口重放

$this->checkNonce();

}

}

/**

* @desc 校驗token的有效性

*/

private function checkToken(){

if(!isset($_POST['token'])){

Common::outJson('10000','token不能夠為空');

}

$this->token = $_POST['token'];

$key = "token:".$this->token;

$mid = $this->redis->get($key);

if(!$mid){

Common::outJson('10001','token已過期或不合法,請先登錄系統 ');

}

$this->mid = $mid;

}

/**

* @desc 校驗簽名

*/

private function checkSign(){

if(!isset($_GET['sign'])){

Common::outJson('10002','sign校驗碼為空');

}

$this->sign = $_GET['sign'];

$postParams = $_POST;

$params = [];

foreach($postParams as $k=>$v) {

$params[] = sprintf("%s%s", $k,$v);

}

sort($params);

$apiSerect = $this->_config['apiSerect'];

$str = sprintf("%s%s%s", $apiSerect, implode('', $params), $apiSerect);

if ( md5($str) != $this->sign ) {

Common::outJson('10004','傳遞的數據被篡改,請求不合法');

}

}

/**

* @desc nonce校驗預防接口重放

*/

private function checkNonce(){

if(!isset($_POST['nonce'])){

Common::outJson('10003','nonce為空');

}

$this->nonce = $_POST['nonce'];

$nonceKey = sprintf("sign:%s:nonce:%s", $this->sign, $this->nonce);

$nonV = $this->redis->get($nonceKey);

if ( !empty($nonV)) {

Common::outJson('10005','該url已經被調用過,不能夠重復使用');

} else {

$this->redis->set($nonceKey,$this->nonce,360);

}

}

}

config.php

return [

//redis的配置

'redis' => [

'host' => 'localhost',

'port' => '6379',

'auth' => '123456',

'db_id' => 0,//redis的第幾個數據庫倉庫

],

//是否開啟接口校驗,true開啟,false,關閉

'checkApi'=>true,

//加密sign的鹽值

'apiSerect'=>'test_jwt'

];

login.php

/**

* @desc 自動加載類庫

*/

spl_autoload_register(function($className){

$arr = explode('\\',$className);

include $arr[0].'/'.$arr[1].'.php';

});

use Core\Common;

use Core\RedisService;

if(!isset($_POST['username']) || !isset($_POST['pwd']) ){

Common::outJson(-1,'請輸入用戶名和密碼');

}

$username = $_POST['username'];

$pwd = $_POST['pwd'];

if($username!='admin' || $pwd!='123456' ){

Common::outJson(-1,'用戶名或密碼錯誤');

}

//創建token并存入redis,token對應的值為用戶的id

$config = Common::getConfig('redis');

$redis = RedisService::getInstance($config);

//假設用戶id為2

$uid = 2;

$token = Common::createToken($uid);

$key = "token:".$token;

$redis->set($key,$uid,3600);

$data['token'] = $token;

Common::outJson(0,'登錄成功',$data);

user.php

/**

* @desc 自動加載類庫

*/

spl_autoload_register(function($className){

$arr = explode('\\',$className);

include $arr[0].'/'.$arr[1].'.php';

});

use Core\Controller;

use Core\Common;

class UserController extends Controller{

/***

* @desc 獲取用戶信息

*/

public function getUser(){

$userInfo = [

"id"=>2,

"name"=>'巴八靈',

"age"=>30,

];

if($this->mid==$_POST['mid']){

Common::outJson(0,'成功獲取用戶信息',$userInfo);

}else{

Common::outJson(-1,'未找到該用戶信息');

}

}

}

//獲取用戶信息

$user = new UserController();

$user->getUser();

演示用戶登錄

簡要描述:

用戶登錄接口

請求URL:

http://localhost/login.php

請求方式:

POST

參數:

參數名

必選

類型

說明

username

string

用戶名

pwd

string

密碼

返回示例

{

"code": 0,

"msg": "登錄成功",

"data": {

"token": "86b58ada26a20a323f390dd5a92aec2a"

}

}

{

"code": -1,

"msg": "用戶名或密碼錯誤"

}

演示獲取用戶信息

簡要描述:

獲取用戶信息,校驗整個接口安全的流程

請求URL:

http://localhost/user.php?sign=f39b0f2dea817dd9dbef9e6a2bf478de

請求方式:

POST

參數:

參數名

必選

類型

說明

token

string

token

mid

int

用戶id

nonce

string

防止用戶重放字符串 md5加密串

timestamp

int

當前時間戳

返回示例

{

"code": 0,

"msg": "成功獲取用戶信息",

"data": {

"id": 2,

"name": "巴八靈",

"age": 30

}

}

{

"code": "10005",

"msg": "該url已經被調用過,不能夠重復使用"

}

{

"code": "10004",

"msg": "傳遞的數據被篡改,請求不合法"

}

{

"code": -1,

"msg": "未找到該用戶信息"

}

文章完整代碼地址

后記

上面完整的實現了整個api的安全過程,包括接口token生成時效性合法性驗證,接口數據傳輸防篡改,接口防重放實現。僅僅靠這還不能夠最大限制保證接口的安全。條件滿足的情況下可以使用https協議從數據底層來提高安全性,另外本實現過程token是使用redis存儲,下一篇文章我們將使用第三方開發的庫實現JWT的規范操作,來替代redis的使用。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的php 接口安全解决方案,php接口数据安全解决方案(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本寂寞少妇 | 欧美鲁鲁| 国产激情四射 | 福利视频在线免费观看 | 欧美激情片一区二区 | 国产精品一区二三区 | 538精品一线 | 国产suv精品一区二区四 | 香港三级在线视频 | 被室友玩屁股(h)男男 | 久久桃色| 免费黄色大片 | 欧美色999| 美女操操操| av 日韩 人妻 黑人 综合 无码 | 国产美女视频免费观看下载软件 | 黄色一级片在线播放 | 男女性生活毛片 | 日韩免费一区 | 成人av资源网 | 后入内射欧美99二区视频 | 国产精品国产一区二区三区四区 | 欧美精品一区二区视频 | 亚洲污污视频 | 在线观看中文字幕av | 侵犯亲女在线播放视频 | 日本va在线| 开心激情综合网 | 白嫩情侣偷拍呻吟刺激 | 亚洲亚裔videos黑人hd | 国产成人精品一区二区三 | 欧美在线中文字幕 | 日韩成人在线免费观看 | 久国产视频 | 91精品国产高潮对白 | 亚洲伦理一区二区 | 大肉大捧一进一出好爽视频 | 亚洲中文无码久久 | 国产av无码专区亚洲av麻豆 | 伊人久久久久久久久久 | 男男做爰猛烈叫床爽爽小说 | 天天操天天射天天爱 | 四虎视频 | 国产中文字幕在线播放 | 国产乱强伦一区二区三区 | 成人做受视频试看60秒 | 日本人和亚洲人zjzjhd | 在线欧美一区二区 | 日韩欧美中| 亲嘴扒胸摸屁股免费视频日本网站 | 亚洲成网| 欧美自拍偷拍一区 | 老头老太做爰xxx视频 | 国产性自拍 | 亚洲图片一区二区三区 | 亚洲色图21p | 香蕉网在线播放 | 欧美在线www| 黄色动漫免费在线观看 | 国产资源av | 一级黄色大片免费看 | 手机在线看黄色 | 国产剧情一区 | 亚洲欧美日韩综合一区二区 | 九九热在线免费视频 | 越南a级片 | 欧美激情在线看 | 黑鬼巨鞭白妞冒白浆 | 色91| 日韩污视频在线观看 | 美女被艹视频网站 | 少妇喷潮明星 | 欧美一区二区三区久久综合 | 天天摸夜夜添狠狠添婷婷 | 成人精品免费网站 | 日本熟妇色xxxxx日本免费看 | 青青草免费公开视频 | 人妻va精品va欧美va | 国产极品探花 | 一区二区三区四区视频 | 中文字幕色图 | 高潮av在线 | 黑人黄色片| 国产激情视频一区二区三区 | a√国产| 激情国产在线 | 超碰人人在线观看 | 亚洲天堂婷婷 | 女生张开腿让男生插 | 成人av激情 | 波多野吉衣一区 | 老司机免费精品视频 | av国产网站 | 96日本xxxxxⅹxxx70| 亚洲伦理天堂 | 国产免费又爽又色又粗视频 | 天堂a在线 | 美女扒开尿口让男人捅爽 | 青青91|