http://www.thinkphp.cn/topic/66124.html
整理一下,前端向接口請求數據時的驗證:比如我寫了一個文章列表數據接口,那么我需要驗證哪些規則,由此,我想了一下,**除開簽名驗證,大概就只有ssl協議,白名單\[ip,域名,url\],黑名單\[ip,域名,url\],請求頻率\[eg:每10秒,最大請求數\],設備【電腦,手機】,終端瀏覽器\[微信,qq,...\],設置請求方式并禁用curl獲取數據\[保證用戶只能在頁面使用ajax請求\]**。
如果不做請求方式的限制,那么就其他人就能通過curl方式獲取到數據,于是寫了下面一個例子,暫時還沒有加入簽名驗證,后續有時間將把簽名加進去。今天先整理這些:`
1. <?php
2. /**
3. ?*??+----------------------------------------------------------------------
4. ?*??|?ThinkPHP?[?WE?CAN?DO?IT?JUST?THINK?]
5. ?*??+----------------------------------------------------------------------
6. ?*??|?Copyright?(c)?2019?ahai574?All?rights?reserved.
7. ?*??+----------------------------------------------------------------------
8. ?*??|?Licensed?(?++++ahai574++++?)
9. ?*??+----------------------------------------------------------------------
10. ?*??|?Author:?阿海?<764882431@qq.com>
11. ?*??+----------------------------------------------------------------------
12. ?*/
13. /**
14. ?*?請求驗證
15. ?*?demo:
16. ?*?$checkRequest?=?new?CheckRequest();
17. ?*??????$checkRequest->setAjax('get',true);
18. ?*??????$checkRequest->setBlackList('10.0.0.155',false);
19. ?*??????$checkRequest->setWhiteList('10.0.0.15');
20. ?*??????$checkRequest->setDevice('mobile,pc',false);
21. ?*??????$checkRequest->setTerminal('uc,weixin',false);
22. ?*??????$checkRequest->setFrequent(10,3,true);
23. ?*??????$checkRequest->setSsl(false);
24. ?*??????$result?=?$checkRequest->check();
25. ?*?if(!$result['result'])?return?json($result);
26. ?*/
28. namespace?app\common\library;
30. use?think\Controller;
31. use?think\Exception;
32. use?think\facade\Request;
34. classCheckRequestextendsController
35. {
36. /**
37. ?????*?開啟?協議請求?必須是?https
38. ?????*?boolean
39. ?????*/
40. private?$isSsl?=false;
42. /**
43. ?????*?開啟?驗證請求?為?【頁面內】ajax請求
44. ?????*?boolean
45. ?????*/
46. private?$isAjax?=true;
48. /**
49. ?????*?ajax請求方式[eg:[post,get,put]]
50. ?????*?array
51. ?????*/
52. private?$ajax?=[];
54. /**
55. ?????*?是否開啟?頻繁請求驗證
56. ?????*?boolean
57. ?????*/
58. private?$isFrequently?=false;
60. /**
61. ?????*?頻繁請求?的?秒數
62. ?????*?int
63. ?????*/
64. private?$requestTime?=10;
66. /**
67. ?????*?頻繁請求?($requestTime)10秒?內?的?最大訪問次數
68. ?????*?int
69. ?????*/
70. private?$frequency?=50;
72. /**
73. ?????*?是否開啟白名單驗證
74. ?????*?boolean
75. ?????*/
76. private?$isWhiteList?=false;
78. /**
79. ?????*?ip白名單?或者?域名白名單
80. ?????*?[
81. ?????*?完整的域名(eg:http:test.baidu.com),主域名(eg:baidu.com),
82. ?????*?子域名[eg:test.baidu.com],url完整路徑(eg:http://test.baidu.com/test/test.html)
83. ?????*?]
84. ?????*?array
85. ?????*/
86. private?$whiteList?=['127.0.0.1'];
88. /**
89. ?????*?是否開啟黑名單驗證??【優先級大于白名單】
90. ?????*?boolean
91. ?????*/
92. private?$isBlackList?=false;
94. /**
95. ?????*?ip黑名單?或者?域名黑名單
96. ?????*?[
97. ?????*?完整的域名(eg:http:test.baidu.com),主域名(eg:baidu.com),
98. ?????*?子域名[eg:test.baidu.com],url完整路徑(eg:http://test.baidu.com/test/test.html)
99. ?????*?]
100. ?????*?array
101. ?????*/
102. private?$blackList?=[];
104. /**
105. ?????*?是否開啟設備驗證
106. ?????*?boolean
107. ?????*/
108. private?$isDevice?=false;
110. /**
111. ?????*?設備類型?手機[mobile]?電腦['pc']?
112. ?????*?array
113. ?????*/
114. private?$device?=['mobile'];
116. /**
117. ?????*?是否開啟終端驗證
118. ?????*?boolean
119. ?????*/
120. private?$isTerminal?=false;
122. /**
123. ?????*?終端瀏覽器類型?(eg:['weixin','qq','baidu','uc'])
124. ?????*?array
125. ?????*/
126. private?$terminal?=['weixin'];
128. /**
129. ?????*?構造函數?constructor.
130. ?????*/
131. publicfunction?__construct($config?=[])
132. {
133. ????????parent::__construct();
135. if(isset($config)&&!is_array($config)){
136. thrownewException("構造參數config必須是數組");
137. }
139. ????????$this->isSsl?=?isset($config['isSsl'])&&!empty($config['isSsl'])??$config['isSsl']:?$this->isSsl;
141. ????????$this->isAjax?=?isset($config['isAjax'])&&!empty($config['isAjax'])??$config['isAjax']:?$this->isAjax;
142. ????????$this->ajax?=?isset($config['ajax'])&&?is_array($config['ajax'])??$config['ajax']:?$this->ajax;
144. ????????$this->isFrequently?=?isset($config['isFrequently'])&&!empty($config['isFrequently'])??$config['isFrequently']:?$this->isFrequently;
145. ????????$this->requestTime?=?isset($config['requestTime'])&&!empty($config['requestTime'])??$config['requestTime']:?$this->requestTime;
146. ????????$this->frequency?=?isset($config['frequency'])&&!empty($config['frequency'])??$config['frequency']:?$this->frequency;
148. ????????$this->isWhiteList?=?isset($config['isWhiteList'])&&!empty($config['isWhiteList'])??$config['isWhiteList']:?$this->isWhiteList;
149. ????????$this->whiteList?=?isset($config['whiteList'])&&?is_array($config['whiteList'])??array_merge($this->whiteList,?$config['whiteList']):?$this->whiteList;
151. ????????$this->isBlackList?=?isset($config['isBlackList'])&&!empty($config['isBlackList'])??$config['isBlackList']:?$this->isBlackList;
152. ????????$this->blackList?=?isset($config['blackList'])&&?is_array($config['blackList'])??array_merge($this->blackList,?$config['blackList']):?$this->blackList;
154. ????????$this->isDevice?=?isset($config['isDevice'])&&!empty($config['isDevice'])??$config['isDevice']:?$this->isDevice;
155. ????????$this->device?=?isset($config['device'])&&?is_array($config['device'])??$config['device']:?$this->device;
157. ????????$this->isTerminal?=?isset($config['isTerminal'])&&?is_array($config['isTerminal'])??$config['isTerminal']:?$this->isTerminal;
158. ????????$this->terminal?=?isset($config['terminal'])&&?is_array($config['terminal'])??$config['terminal']:?$this->terminal;
160. }
162. /**
163. ?????*?檢測請求行為
164. ?????*?@return?boolean
165. ?????*/
166. publicfunction?check()
167. {
168. //驗證黑名單--
169. if($this->isBlackList){
170. //ip,主域名,包含協議域名,請求的url完整路徑,?主域名
171. ????????????$requestList?=[Request::ip(),Request::host(),Request::domain(),Request::url(true),Request::rootDomain()];
173. if(!empty(array_intersect($this->blackList,?$requestList))){
174. return['result'=>false,'errorMsg'=>'域名[ip]已被禁用','code'=>200];
175. }else{
176. //讀取數據庫黑名單表
177. ????????????????$list?=?db('request_blacklist')
178. ->whereOr('ip','eq',Request::ip())
179. ->whereOr('domain','eq',Request::domain())
180. ->whereOr('domain','eq',Request::host())
181. ->whereOr('domain','eq',Request::rootDomain())
182. ->whereOr('domain','eq',Request::url(true))
183. ->find();
184. if(!is_null($list)){
185. return['result'=>false,'errorMsg'=>'域名[ip]已被禁用','code'=>200];
186. }
187. }
190. }
192. //驗證ssl協議
193. if($this->isSsl){
194. if(!Request::isSsl()){
195. return['result'=>false,'errorMsg'=>'請求協議必須是https協議','code'=>200];
196. }
197. }
199. //驗證是否ajax?必須是頁面內的請求??[避開curl請求,瀏覽器直接輸入地址]
200. if($this->isAjax){
201. if(empty($this->ajax)){
202. if(!Request::isAjax()){
203. return['result'=>false,'errorMsg'=>'非法請求','code'=>200];
204. }
205. }else{
206. if(!in_array(Request::method(),?$this->ajax))
207. {
208. return['result'=>false,'errorMsg'=>'非法請求','code'=>200];
209. }
210. }
211. }
213. //驗證請求頻率
214. if($this->isFrequently){
215. ????????????$data?=[
216. 'method'=>Request::method(),
217. 'param'=>??json_encode(Request::param()),
218. 'ip'=>Request::ip(),
219. 'url'=>Request::url(true),
220. 'http_user_agent'=>??$_SERVER['HTTP_USER_AGENT'],
221. 'is_mobile'=>Request::isMobile()?1:0,
222. 'create_time'=>??time()
223. ];
224. ????????????db('request_log')->insert($data);
225. ????????????$where?=[
226. ['ip','=',Request::ip()],
227. ['create_time',">=",time()-$this->requestTime]
228. ];
229. ????????????$list?=?db('request_log')->where($where)->count('id');
230. if($list?>?$this->frequency){
231. ????????????????$data?=[
232. 'ip'=>Request::ip(),
233. 'domain'=>Request::domain(),
234. 'content'=>'頻繁請求',
235. 'create_time'=>??time()
236. ];
237. ????????????????db('request_blacklist')->insert($data);
238. return['result'=>false,'errorMsg'=>'請求過于頻繁,請稍后再進行請求','code'=>200];
239. }
240. }
242. //驗證ip域名白名單
243. if($this->isWhiteList){
244. //ip,主域名,包含協議域名,請求的url完整路徑,?主域名
245. ????????????$requestList?=[Request::ip(),Request::host(),Request::domain(),Request::url(true),Request::rootDomain()];
246. if(?empty(array_intersect($this->whiteList,?$requestList))){
247. //讀取數據庫黑名單表
248. ?????????????????$list?=?db('request_whitelist')
249. ->whereOr('ip','eq',Request::ip())
250. ->whereOr('domain','eq',Request::domain())
251. ->whereOr('domain','eq',Request::host())
252. ->whereOr('domain','eq',Request::rootDomain())
253. ->whereOr('domain','eq',Request::url(true))
254. ->find();
255. if(is_null($list)){
256. return['result'=>false,'errorMsg'=>'域名[ip]不在白名單中','code'=>200];
257. }
258. }
259. }
261. //驗證設備類型
262. if($this->isDevice){
263. ????????????$requestDevice?=Request::isMobile()?'mobile':'pc';
264. if(!in_array($requestDevice,?$this->device)){
265. return['result'=>false,'errorMsg'=>'不支持當前設備','code'=>200];
266. }
267. }
269. //驗證終端--
270. if($this->isTerminal){
271. ????????????$requestTerminal?=?$this->getBrowser();
272. if(!in_array($requestTerminal,?$this->terminal)){
273. return['result'=>false,'errorMsg'=>'不支持當前瀏覽器','code'=>200];
274. }
275. }
277. return['result'=>true,'msg'=>'請求通過','code'=>200];
279. }
281. /**
282. ?????*?設置?ip?域名?白名單
283. ?????*?@param?$blackList?array
284. ?????*?@param?$isBlackList?boolean
285. ?????*/
286. publicfunction?setBlackList($blackList?=[],?$isBlackList?=true)
287. {
288. if(!is_array($blackList))
289. {
290. ????????????$blackList?=?explode(",",?$blackList);
291. }
293. if(!is_bool($isBlackList))
294. {
295. thrownewException("參數isBlackList必須是boolean");
296. }
298. ????????$this->blackList?=?array_merge($this->blackList,?$blackList);
299. ????????$this->isBlackList?=?$isBlackList;
301. return?$this;
302. }
304. /**
305. ?????*?判斷是否微信瀏覽器
306. ?????*/
307. privatefunction?getBrowser()
308. {
309. ???????$agent???=?$_SERVER['HTTP_USER_AGENT'];
310. if(strpos($agent,'MicroMessenger')!==false)
311. {
312. return"weixin";
313. }elseif(strpos($agent,'QQBrowser')!==false)
314. {
315. return"qq";
316. }elseif(strpos($_SERVER['HTTP_USER_AGENT'],'UCBrowser')!==false||strpos($_SERVER['HTTP_USER_AGENT'],'UCWEB')!==false)
317. {
318. return"uc";
319. }elseif(strpos($agent,'baidu')!==false)
320. {
321. return"baidu";
322. }else
323. {
324. return"other";
325. }
326. }
328. /**
329. ?????*?設置是否開啟?ajax請求驗證
330. ?????*?@param?$ajax?array?[post,get]?
331. ?????*?@param?$isAjax?boolean
332. ?????*/
333. publicfunction?setAjax(?$ajax?=[],$isAjax?=true)
334. {
335. if(!is_array($ajax)){
336. ????????????$ajax?=?explode(",",?$ajax);
337. }
339. if(!is_bool($isAjax)){
340. thrownewException("參數isAjax必須是boolean類型");
341. }
343. ????????$this->ajax?=?array_map('strtoupper',$ajax);
344. ????????$this->isAjax?=?$isAjax;
346. return?$this;
347. }
349. /**
350. ?????*?設置是否開啟?協議驗證
351. ?????*?@param?$isSsl?boolean
352. ?????*/
353. publicfunction?setSsl(?$isSsl?=true)
354. {
355. if(!is_bool($isSsl)){
356. thrownewException("參數isSsl必須是boolean類型");
357. }
359. ????????$this->isSsl?=?$isSsl;
361. return?$this;
362. }
364. /**
365. ?????*?設置?頻繁請求的參數
366. ?????*?@param?$isFrequently?是否開啟驗證?
367. ?????*?@param?$requestTime?設置驗證的時間數
368. ?????*?@param?$frequently?設置在規定的時間內的最大請求數
369. ?????*/
370. publicfunction?setFrequent($requestTime?=10,?$frequency?=50,?$isFrequently?=true)
371. {
372. if(!is_int($requestTime)||!is_int($frequency)){
373. thrownewException("參數[requestTime,requestTime]必須是integer類型");
374. }
376. if(!is_bool($isFrequently)){
377. thrownewException("參數frequently必須是boolean類型");
378. }
380. ????????$this->requestTime?=?$requestTime;
381. ????????$this->frequency?=?$frequency;
382. ????????$this->isFrequently?=?$isFrequently;
384. return?$this;
385. }
387. /**
388. ?????*?設置?ip?域名?白名單
389. ?????*?@param?$whiteList?array
390. ?????*?@param?$isWhiteList?boolean
391. ?????*/
392. publicfunction?setWhiteList($whiteList?=[],?$isWhiteList?=true)
393. {
394. if(!is_array($whiteList))
395. {
396. ???????????$whiteList?=?explode(",",?$whiteList);
397. }
399. if(!is_bool($isWhiteList))
400. {
401. thrownewException("參數isWhiteList必須是boolean");
402. }
404. ????????$this->whiteList?=?array_merge($this->whiteList,?$whiteList);
405. ????????$this->isWhiteList?=?$isWhiteList;
407. return?$this;
408. }
410. /**
411. ?????*?設置?設備類型
412. ?????*?@param?$device?array?|?string?
413. ?????*?@param?$isDevice?是否開啟驗證
414. ?????*/
415. publicfunction?setDevice($device?=[],?$isDevice?=true)
416. {
417. if(!is_array($device))
418. {
419. ????????????$device?=?explode(",",?$device);
420. }
422. if(!is_bool($isDevice))
423. {
424. thrownewException("參數isDevice必須是boolean");
425. }
427. ????????$this->device?=?$device;
428. ????????$this->isDevice?=?$isDevice;
430. return?$this;
431. }
433. /**
434. ?????*?設置?設備類型
435. ?????*?@param?$terminal?array?|?string?
436. ?????*?@param?$isTerminal?是否開啟驗證
437. ?????*/
438. publicfunction?setTerminal($terminal?=[],?$isTerminal?=true)
439. {
441. if(!is_array($terminal))
442. {
443. ????????????$terminal?=?explode(",",?$terminal);
444. }
446. if(!is_bool($isTerminal))
447. {
448. thrownewException("參數isTerminal必須是boolean");
449. }
451. ????????$this->terminal?=?$terminal;
452. ????????$this->isTerminal?=?$isTerminal;
454. return?$this;
455. }
459. }
復制代碼
`暫時記錄這些...
- 空白目錄1
- RBAC
- RBAC權限模型[完整]
- 你知道權限管理的RBAC模型嗎?
- rbac 一個用戶對應多個賬號_如何設計一個強大的權限系統
- Postman 快速使用(設置環境變量)
- postman的使用方法詳解!最全面的教程
- Postman常用的幾個功能
- ThinkPHP項目總結
- thinkphp5 遞歸查詢所有子代,查詢上級,并且獲取層級
- PHP原生項目之留言板
- 智慧校園
- PHP如何實現訂單的延時處理詳解
- VUE
- const {data:res} = await login(this.loginForm)
- Vue中的async和await的使用
- PHP實現消息推送(定時輪詢)
- tp5 計算兩個日期之間相差的天數
- 使用jquery的ajax方法獲取下拉列表值
- jQuery實現select下拉框選中數據觸發事件
- SetFocus 方法
- 快來了解下TP6中的超級函數app()!
- PHP socket 服務器框架 workerman
- 程序員如何才能成為獨立開發者?
- PHP 錯誤處理
- php面向對象類中的$this,static,final,const,self及雙冒號 :: 這幾個關鍵字使用方法。
- 小白教你玩轉php的閉包
- 關于TP6項目搭建的坑(多應用模式)
- ThinkPHP6.0 與5.0的差別及坑點
- axios在vue項目中的使用實例詳解
- php中的類、對象、方法是指什么
- 聊一聊PHP的依賴注入(DI) 和 控制反轉(IoC)
- 深入理解控制反轉(IoC)和依賴注入(DI)
- Private,Public,Protected
- ThinkPHP5(目錄,路徑,模式設置,命名空間)
- 在 ThinkPHP6 中使用 Workerman
- 介紹thinkphp lock鎖的使用和例子
- php中_initialize()函數與 __construct()函數的區別說明
- api接口數據-驗證-整理
- api接口數據-驗證-整理【續】
- TP6容易踩得坑【原創】
- TP6的日志怎么能記錄詳細的日志?
- 是否需要模型分層
- PHP面試題 全網最硬核面試題來了 2021年學習面試跳槽必備(一)
- MySQL單表數據量過千萬,采坑優化記錄,完美解決方案
- MySql表分區(根據時間timestamp)
- MySQL大表優化方案
- 閑言碎語
- 數據庫外鍵的使用
- 深入理解thinkphp、laravel等框架中容器概念
- vue做前端,thinkphp6做后臺,項目部署
- 簡單MVC架構的PHP留言本
- TP5里面extend和vendor的區別
- 在mysql數據庫中制作千萬級測試表
- MySQL千萬級的大表要怎么優化
- ThinkPHP關聯模型操作實例分析
- lcobucci/jwt —— 一個輕松生成jwt token的插件
- RESTful API 設計指南
- MySQL如何為表字段添加索引
- ThinkPHP6.0快速開發手冊(案例版)
- tp5 靜態方法和普通方法的區別
- 數據字典功能
- mysql中的數據庫ID主鍵的設置問題
- 基于角色的權限控制(django內置auth體系)
- RBAC系統經典五張表
- 什么是接口文檔,如何寫接口,有什么規范?
- thinkphp5.0自定義驗證器