【玩转 Postman 接口测试与开发2_018】第14章:利用 Postman 初探 API 安全测试

book cover for the 2nd version

《API Testing and Development with Postman》最新第二版封面

文章目录

  • 第十四章 API 安全测试
    • 1 OWASP API 安全清单
      • 1.1 相关背景
      • 1.2 OWASP API 安全清单
      • 1.3 认证与授权
      • 1.4 破防的对象级授权(Broken object-level authorization)
      • 1.5 破防的属性级授权(Broken property-level authorization)
      • 1.6 不受控制的资源消耗(Unrestricted resource consumption)
      • 1.7 不受限制地访问业务流(Unrestricted access to business workflows)
      • 1.8 不安全地使用 API 接口(Unsafe consumption of APIs)
    • 2 模糊测试(Fuzzy)
      • 2.1 相关概念
      • 2.2 实战:在 Postman 中执行模糊测试
      • 2.3 绕开 Collection Runner 的测试方案
    • 3 利用 Postman 内置随机变量实现模糊测试
    • 4 小结

写在前面
本章为全书的倒数第二章,作者简要介绍了 API 安全测试的相关概念,并对 OWASP API 安全清单和模糊测试(Fuzzy Testing)进行了重点讲解;后半部分作者利用数据驱动测试演示了模糊测试在 Postman 中的具体应用,只可惜在实现方案和叙述的条理性上较为敷衍,导致我在实测过程中又踩了不少坑。特此梳理出来,既是对自己创新方案的复盘,也能让更多后来者少走弯路。

第十四章 API 安全测试

本章概要

  • OWASP API 安全清单
  • Postman 进行模糊测试(Fuzz testing)的方法

1 OWASP API 安全清单

1.1 相关背景

  • OWASP(Open Web Application Security Project)是一个非营利组织,专注于提高软件安全性;
  • 提供免费、开放的资源,如工具、文档、论坛等,帮助开发者和安全人员构建安全的应用程序;
  • 知名项目包括 OWASP Top 10(十大 Web 应用安全风险)和 API Security Top 10(API安全十大风险);
  • 相关资源:
    • 网站门户:https://owasp.org/;
    • 2023 最新版 API 安全清单:https://owasp.org/www-project-api-security/;

1.2 OWASP API 安全清单

  • API Security Top 10 是 OWASP 针对 API 安全的核心文档,罗列了 API 面临的十大安全风险。
  • 适用于开发者、安全工程师和架构师,帮助识别和缓解API安全威胁。

1.3 认证与授权

黑客最先尝试的攻击方式是身份验证,即通过用户名密码攻击。

最简单的方式是暴力破解(brute-force attack),因此 API 接口应采取在一定时间段内 限制登录次数 的防护措施。

具体实现:以 GitPod 演示项目为例,可利用 Postman 内置的随机数据变量高频多次调用登录接口(多次手动点击或 Collection Runner 设置迭代次数):

测试脚本:

for (let i = 0, len = 50; i < len; i++) {pm.sendRequest({url: pm.variables.replaceIn('{{base_url}}/token'),method: 'POST',header: { 'Content-Type': 'multipart/form-data'},body: {mode: "formdata",formdata: [{ key: 'username', value: pm.variables.replaceIn('{{$randomUserName}}') },{ key: 'password', value: pm.variables.replaceIn('{{$randomPassword}}') }]}},function (err, resp) {if (err) {console.error(JSON.parse(err));return;}pm.test(`${i + 1}: Response JSON have detail attribute`, function () {pm.expect(resp.json()).to.eql({ "detail": "Incorrect user name or password" });});})
}

实测结果(鉴权接口疑似不具备限制登录次数功能):

图 14.1 构造不同的用户名和密码,多次高频调用登录接口,模拟暴力破解过程

【图 14.1 构造不同的用户名和密码,多次高频调用登录接口,模拟暴力破解过程】

1.4 破防的对象级授权(Broken object-level authorization)

这是 2023 年十大安全清单排名第一的高风险议题:

  • 问题描述:未正确验证用户对对象的访问权限,导致越权访问。
  • 应对措施:实施严格的权限验证,确保用户只能访问授权资源。
  • 示例:用登录普通用户(user1/12345)的登录令牌去访问管理员帐号,看看示例项目是否会响应 403 错误。

实测结果:

图 14.2 用 user1 的登录令牌访问管理员 admin 的帐号信息,后台报 403 错误(符合预期)

【图 14.2 用 user1 的登录令牌访问管理员 admin 的帐号信息,后台报 403 错误(符合预期)】

1.5 破防的属性级授权(Broken property-level authorization)

示例:用 user1/12345 登录,先用 "user1" 为创建人(即 create_by 字段)添加一个正常的待办项,然后看看是否可以通过 PUT 请求篡改该创建人信息(例如改为 "user2")。

测试脚本:

// PUT request's Post-response
pm.collectionVariables.set('reqPut', pm.request);// Pre-request
pm.sendRequest(pm.collectionVariables.get('reqPut'),function(err, resp) {if(err) {console.error('Updated failure:', err);return;}pm.test('PUT req: status code should be 200', () => {console.log(resp)pm.expect(resp.code).to.eq(200);});}
)// Post-response
pm.test('The creator should not be updated (user1) after running PUT req',() => {const [{ created_by: creator }] = pm.response.json();pm.expect(creator).to.eql('user1')});

实测结果:

图 14.3 实测属性级授权漏洞(篡改失败,符合预期)

【图 14.3 实测属性级授权漏洞(篡改失败,符合预期)】

但实测发现,在创建待办项时人为设置创建人为 非当前登录用户(如 "user2"),最后仍然创建成功了,说明该接口还是有问题的:

图 14.4 创建任务时篡改创建人信息,最终任务创建成功,说明该接口仍然支持篡改信息

【图 14.4 创建任务时篡改创建人信息,最终任务创建成功,说明该接口仍然支持篡改信息】

1.6 不受控制的资源消耗(Unrestricted resource consumption)

方式一:通过耗尽所有系统资源来损害系统,导致系统瘫痪(denial-of-service attacks,拒绝服务攻击);

方式二:由于未对接口调用次数进行限制,大量请求将拖慢响应速度;如果接口调用了第三方付费资源,还会产生大量费用。

1.7 不受限制地访问业务流(Unrestricted access to business workflows)

攻击者可能会利用抓包、监控请求数据等方式获取系统内部通信 API,从而获悉内部工作流结构,给系统带来严重威胁(例如恶意逃票等)。

应对措施:仔细考虑暴露了哪些接口;严格控制接口访问权限。

1.8 不安全地使用 API 接口(Unsafe consumption of APIs)

典型案例:引用了被黑客攻击的第三方 API。

这类测试较为棘手,可能需要搭建一个模拟服务器,让从第三方 API 响应的数据在该模拟器上先行缓冲,或者模拟危险数据进行测试,看看本地后台是否能够鉴别该类数据。

2 模糊测试(Fuzzy)

2.1 相关概念

定义:模糊测试(Fuzzy) 是一种通过向程序提供无效、随机或意外的输入来发现漏洞和错误的测试技术。

主要特征:

  • 非通用测试技术
  • 有助于发现未考虑到、或未测试到的问题

具体的运行方式:

  • 手动执行:通过在 UI 中输入伪随机数据来完成(极少);
  • 编程执行:以程序的形式运行(绝大多数)。工具如 PeachFuzzer 或自定义输入集。

输入的生成:

  • 生成大量随机或半随机数据,可能包含格式错误或危险字符(如转义字符、引号等)。
  • 输入通常是随机的,但有一些边界限制(例如,字节 vs ASCII/Unicode 字符串)。
  • 输入可以偏向已知的“危险”字符(例如转义字符、引号等)。

输入内容的具体方式:

  • 通过命令行参数注入
  • 通过文件输入
  • 通过网络协议
  • 通过 API 输入(特别适合模糊测试,易于用程序控制)

模糊查询的应用场景:

  • 安全测试场景:揭示未能预见的攻击方向,发现错误处理机制中的薄弱环节等;
  • API 测试场景:具有易于访问且数量巨大的测试输入,尤其适合 API 测试。

2.2 实战:在 Postman 中执行模糊测试

GitHub 开源项目 Big List of Naughty StringsJSON 文件为数据源,利用 Collection RunnerGitPod 演示项目 ToDo List App 进行基于数据驱动的模糊测试,看看 POST /tasks 接口在大量随机输入下的响应情况。

首先从开源项目下载原始数据文件 blns.base64.json。该原始数据为 Base64 编码的字符串数组:

["", "dW5kZWZpbmVk", "dW5kZWY=", "bnVsbA==", ...
]

使用前需要先处理成如下格式(可使用 vim 宏的批量操作完成):

[{"naughtyString":""}, {"naughtyString":"dW5kZWZpbmVk"}, {"naughtyString":"dW5kZWY="}, {"naughtyString":"bnVsbA=="}, ...
]

然后创建测试集合 FuzzyTest 以及 POST 请求 Create a task,其 URL 设置为 {{base_url}}/tasks,其中 base_url 为集合变量,其值为 GitPod 演示项目的基础 URL(启动链接:https://gitpod.io/new/#https://github.com/djwester/todo-list-testing)。

接着,在测试请求的请求体中输入如下内容(这里有个大坑,后面会讲):

{"description": "{{naughtyString}}","status": "Draft"
}

上述代码中的 naughtyString 为数据驱动测试启动后、经 Pre-request 脚本处理得到的动态变量:

const atob = require('atob');
const encoded_string = pm.iterationData.get("naughtyString");
pm.collectionVariables.set('naughtyString', atob(encoded_string));

对应的 Post-response 响应后脚本如下:

pm.test("Status code is 201", function() {pm.response.to.have.status(201);
});

一切准备就绪后,启动 Collection Runner,加载 JSON 映射文件,执行模糊测试:

图 14.5 利用 Collection Runner,发起基于JSON 文件数据驱动的模糊测试

【图 14.5 利用 Collection Runner,发起基于JSON 文件数据驱动的模糊测试】

由于是分别读取每行数据并调用创建接口,整个过程需要多等些时间,最终得到结果:

图 14.6 Collection Runner 运行结束后的实测截图

【图 14.6 Collection Runner 运行结束后的实测截图】

由于作者演示时用的是本地部署的 ToDo List App,全套数据测完只用了 1'14",和我实测时的 23'56" 真是天壤之别(没办法,Python 基础有限,几次尝试本地部署都失败了)。但奇怪的是,除了 10 个请求因为网络原因发送失败,其余 666 个都成功了,并没有报错。

可高兴不到一分钟,我就知道出问题了。作者并没有交代要用 user2 登录,而我新增任务前压根儿就没登录,导致后续的数据清空全部失败了:

图 14.7 由于新增任务时没有登录,导致后续的批量删除全部失败(神坑)

【图 14.7 由于新增任务时没有登录,导致后续的批量删除全部失败(神坑)】

没办法,只能重置项目,重新来过……

Ctrl + C 中断 GitPod 项目,运行重置数据命令 poetry run python remove_tables.py,然后执行 make run-dev 重新启动。

这次先用 user2/12345 换取登录令牌,再到新增接口中完成鉴权:

图 14.8 用 user2 的登录令牌完成新增接口的鉴权设置

【图 14.8 用 user2 的登录令牌完成新增接口的鉴权设置】

然后只选取新增接口,再次上传 JSON 数据集运行 Collection Runner

图 14.9 重新运行 Collection Runner 的配置界面截图

【图 14.9 重新运行 Collection Runner 的配置界面截图】

也不知道是不是这份死磕精神感动了马克思,第二次运行居然全部成功了:

图 14.10 第二次运行结果截图(676 条数据全部新增成功)

【图 14.10 第二次运行结果截图(676 条数据全部新增成功)】

接着在浏览器查看项目首页,也没有书中说的 alert 注入问题(当真欧皇附体?):

img14.11

借着这波好运,赶紧再跑一遍数据批量清空。在 GET {{base_url}}/task 接口的响应后脚本中输入以下内容(直接用 JS 脚本批量删除,书中方法太过陈旧,还得再消耗一次 Collection Runner 免费额度,不知道作者怎么想的):

const tasks = pm.response.json();
const task_ids = tasks.map(t => t.id);const base_url = pm.collectionVariables.get('base_url');
const auth = {type: 'bearer',bearer: [{key: 'token',value: pm.collectionVariables.replaceIn('{{token}}'),type: 'string'}]
};
const getCallback = task_id => (err, response) => {if(err) {console.error(err);return;}pm.test(`Deleting id(${task_id}): Status should be OK`, function() {pm.expect(response.status).to.eql('OK');});
};for(const id of task_ids) {// Delete the task by idpm.sendRequest({url: `${base_url}/tasks/${id}`,method: 'DELETE',auth}, getCallback(id));
}

结果还是报错:

img14.12

仔细一想,真相大白了:新增接口必须在请求体中手动指定 created_by 字段,否则 一律按匿名处理(就当是作者故意挖的坑吧)。

只有再重来一遍了:

img14.13

再次执行批量删除,只有一次是后台原因删除失败,五次请求未发送,其余全部删除成功,终于熬出头了:

img14.14

2.3 绕开 Collection Runner 的测试方案

其实只要具备 JavaScript 基础,完全可以跳过 Collection Runner 的限制,在 Pre-request / Post-response 脚本中实现批量新增和删除。

批量新增的纯 JS 脚本实现:

  1. 将原始 JSON 数据集不经任何处理直接放到 Postman 的私有模块中,例如 my-blns

    const data = ["", "dW5kZWZpbmVk", "dW5kZWY=", "bnVsbA==", "TlVMTA==", "KG51bGwp", // ..."e3sgIiIuX19jbGFzc19fLl9fbXJvX19bMl0uX19zdWJjbGFzc2VzX18oKVs0MF0oIi9ldGMvcGFz","c3dkIikucmVhZCgpIH19"
    ];
    module.exports = {data
    };
    
  2. 新建请求 GET {{base_url}}/tasks,用于在批量新增后查询总的待办项列表:

    1. Pre-request 中输入以下脚本:
    const atob = require('atob');
    const { data } = pm.require('your/package/path/to/my-blns');
    // console.log(data.length);const postRequest = description => ({url: pm.collectionVariables.replaceIn('{{base_url}}/tasks'),method: 'POST',header: { 'Content-Type': 'application/json' },body: {mode: 'raw',raw: JSON.stringify({description,status: "Draft",created_by: "user2"})}
    });data.map(d => atob(d)).map((description, i) => pm.sendRequest(postRequest(description), (err, resp) => {if(err) {console.error(err);return;}pm.test(`Create task_${i+1} completed: the status code should be 201`,() => pm.expect(resp.code).to.eql(201));}));
    
    1. Post-response 输入以下脚本:

      pm.test('Task list length should be greater than 0', function () {pm.expect(pm.response.json()).to.be.an('array').and.to.have.lengthOf.at.least(1, "Task list length should be greater than 0");
      });
      
  3. 至于批量删除,刚才实测过程中已经看过脚本了,这里只说明一下实现逻辑。利用列表查询接口 GET {{base_url}}/tasks 获取到任务列表后,批量提取任务列表的 id;然后分别调用 DELETE 接口 POST {{base_url}}/tasks/:id 完成删除(注意:删除待办项时,别忘了在请求中带上鉴权配置对象 auth)。

这样就可以在 Postman 中随意批量新增和删除待办任务了,完全不受 Collection Runner 的制约。

3 利用 Postman 内置随机变量实现模糊测试

其实就是将上传的 JSON 文件内容用 Postman 内置的各种随机变量实现同样的模糊测试效果,例如将新增接口请求体中的 JSON 改为:

{"description": "{{$randomLoremSentence}}","status": "Draft","created_by": "user2"
}

或者借助测试脚本,引入 lodash 实现更多模糊测试效果:

const _ = require('lodash');
// _.sample(collection): Gets a random element from collection.
const description = _.sample(["{{$randomAbbreviation}}", "{{$randomAdjective}}"]);
const jsonBody = {description,"status", "Draft","created_by": "user2"
}

4 小结

本章内容整体感觉较敷衍,上半部分介绍相关概念几乎全是蜻蜓点水式的描述,后半段实战环节的条理性又明显不如前面的章节,漏掉很多关键细节,且在方案选择上过分依赖 Collection Runner,致使我在实测过程中浪费了不少免费额度。不过依次填完这些坑后,我也有机会用纯 JavaScript 脚本的方式实现待办任务的批量创建与删除,顺便学习了用 pm.sendRequest() 发送 POST 请求和 DELETE 请求的写法,也算是因祸得福了吧。

后记
最后再跟大家分享个操作技巧,遇到不会写的 Postman 脚本,可以利用其自带的 AI 机器人 Postbot 直接给答案。本章实测中几种 pm.sendRequest() 的写法就是这么来的,比查官方文档快多了。大家一定要学会使用 AI 工具,千万不要故步自封,成为 AI 时代的 “新文盲”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/13289.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL的 MVCC详解

MVCC是多版本并发控制&#xff0c;允许多个事务同时读取和写入数据库&#xff0c;而无需互相等待&#xff0c;从而提高数据库的并发性能。 在 MVCC 中&#xff0c;数据库为每个事务创建一个数据快照。每当数据被修改时&#xff0c;MySQL不会立即覆盖原有数据&#xff0c;而是生…

【Uniapp-Vue3】z-paging插件组件实现触底和下拉加载数据

一、下载z-paing插件 注意下载下载量最多的这个 进入Hbuilder以后点击“确定” 插件的官方文档地址&#xff1a; https://z-paging.zxlee.cn 二、z-paging插件的使用 在文档中向下滑动&#xff0c;会有使用方法。 使用z-paging标签将所有的内容包起来 配置标签中的属性 在s…

UG NX二次开发(Python)-API函数介绍与应用实例(三)-UFLayer类操作

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1 前言2、UFLayer类说明3、获取当前工作图层4、移动对象到特定的图层1 前言 采用Python语言进行UG NX二次开发的帮助材料很少,采用录制的方法是一种比较容易实现的方式,但是使用UFun函数更容易上…

免费PDF 转换成 Word、PPT、Excel 格式的工具

在当今数字化办公的时代&#xff0c;文件格式的转换需求日益频繁。我们的软件应运而生&#xff0c;它是一款专业的 PDF 转换成 Word、PPT、Excel 格式的工具&#xff0c;为您的办公流程带来极大便利。 下载地址&#xff1a;https://pan.quark.cn/s/8c42ac2e4bf5 核心功能&…

deepseek从网络拓扑图生成说明文字实例

deepseek对话页面中输入问题指令&#xff1a; 我是安全测评工程师&#xff0c;正在撰写系统测评报告&#xff0c;现在需要对系统网络架构进行详细说明&#xff0c;请根据附件网络拓扑图输出详细说明文字。用总分的段落结构&#xff0c;先介绍各网络区域&#xff0c;再介绍网络…

排序算法--希尔排序

希尔排序是插入排序的改进版本&#xff0c;适合中等规模数据排序&#xff0c;性能优于简单插入排序。 // 希尔排序函数 void shellSort(int arr[], int n) {// 初始间隔&#xff08;gap&#xff09;为数组长度的一半&#xff0c;逐步缩小for (int gap n / 2; gap > 0; gap …

【NR-NTN】3GPP Release 18中NR-NTN过程描述

本文参考3GPP规范&#xff1a; 【1】《TS 38.300 V18.4.0 NR; NR and NG-RAN Overall Description; Stage2》 1. 概述 图1展示了一个非地面网络&#xff08;NTN&#xff09;的示例&#xff0c;通过NTN载荷和NTN网关为用户设备&#xff08;UE&#xff09;提供非地面NR接入。图…

python3中错误与异常初识

一. 简介 在 编写 Python时&#xff0c;经常会遇到一些报错信息。接下来开始学习 Python3 中错误和异常。 本文首先初步了解一下 Python3中的错误和异常。 二. python3 中错误与异常初识 Python 中有两种错误&#xff1a;语法错误与异常。 1. 语法错误 Python 的语法错误…

一文解释nn、nn.Module与nn.functional的用法与区别

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;零基础入门PyTorch框架_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 …

“AI隐患识别系统,安全多了道“智能护盾”

家人们&#xff0c;在生活和工作里&#xff0c;咱们都知道安全那可是头等大事。不管是走在马路上&#xff0c;还是在工厂车间忙碌&#xff0c;又或是住在高楼大厦里&#xff0c;身边都可能藏着一些安全隐患。以前&#xff0c;发现这些隐患大多靠咱们的眼睛和经验&#xff0c;可…

口腔扫描仪(口扫)核心算法——点云三维重建

口腔扫描仪&#xff08;口扫&#xff09;的核心算法涉及三维点云获取、配准、去噪、补全及表面重建等多个技术环节&#xff0c;以下从技术原理、关键算法和应用挑战进行详细解析&#xff1a; 1. 数据采集与成像原理 口腔扫描的核心在于快速、高精度获取牙齿与软组织表面几何信…

VLL CCC远程连接实验

1、CE1和CE2的配置 CE1和CE2的配置很简单&#xff0c;只需要在接口E0/0/0上配置ip地址即可&#xff1b; 2、PE1的配置 配置CCC名称为CE1-CE2&#xff0c;将E0/0/1&#xff08;连接CE1&#xff09;作为入接口&#xff0c;入标签为100&#xff0c;出去的时候换成200&#xff0c…

讯飞智作 AI 配音技术浅析(四):语音特征提取与建模

语音特征提取与建模是讯飞智作 AI 配音技术的核心环节&#xff0c;旨在将文本信息转化为高质量的语音信号。该过程依赖于深度学习模型&#xff0c;通过对大量高质量语音数据的训练&#xff0c;提取出关键的声学特征&#xff08;如音素、音节、语调、语速等&#xff09;&#xf…

Java 大视界 -- Java 大数据在智能教育中的应用与个性化学习(75)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也期待你毫无保留地分享独特见解,愿我们于此携手成长,共赴新程!💖 一、…

【MySQL】centos 7 忘记数据库密码

vim /etc/my.cnf文件&#xff1b; 在[mysqld]后添加skip-grant-tables&#xff08;登录时跳过权限检查&#xff09; 重启MySQL服务&#xff1a;sudo systemctl restart mysqld 登录mysql&#xff0c;输入mysql –uroot –p&#xff1b;直接回车&#xff08;Enter&#xff09; 输…

Linux 源码编译安装httpd 2.4,提供系统服务管理脚本并测试

第一种方式 1. 下载 Apache HTTP Server 源代码 首先&#xff0c;从 Apache 官网 下载最新版本的 httpd 2.4 源码&#xff0c;或者直接使用 wget 下载&#xff1a; [rootlocalhost ~]# wget https://downloads.apache.org/httpd/httpd-2.4.36.tar.gz # 解压 [rootlocalhost ~…

【重生之学习C语言----杨辉三角篇】

目录 ​编辑 --------------------------------------begin---------------------------------------- 一、什么是杨辉三角&#xff1f; 二、问题分析 三、算法设计 使用二维数组存储杨辉三角&#xff1a; 递推关系&#xff1a; 格式化输出&#xff1a; 四、代码实现 完…

绿联NAS安装cpolar内网穿透工具实现无公网IP远程访问教程

文章目录 前言1. 开启ssh服务2. ssh连接3. 安装cpolar内网穿透4. 配置绿联NAS公网地址 前言 本文主要介绍如何在绿联NAS中使用ssh远程连接后&#xff0c;使用一行代码快速安装cpolar内网穿透工具&#xff0c;轻松实现随时随地远程访问本地内网中的绿联NAS&#xff0c;无需公网…

C语言-----数据结构从门到精通

1.数据结构基本概念 数据结构是计算机中存储、组织数据的方式&#xff0c;旨在提高数据的访问和操作效率。它是实现高效算法和程序设计的基石。 目标:通过思维导图了解数据结构的知识点,并掌握。 1.1逻辑结构 逻辑结构主要四种类型: 集合&#xff1a;结构中的数据元素之…

使用Pygame制作“打砖块”游戏

1. 前言 打砖块&#xff08;Breakout / Arkanoid&#xff09; 是一款经典街机游戏&#xff0c;玩家控制一个可左右移动的挡板&#xff0c;接住并反弹球&#xff0c;击碎屏幕上方的砖块。随着砖块被击碎&#xff0c;不仅能获得分数&#xff0c;还可以体验到不断加速或复杂的反弹…