TCP与UDP的区别
TCP是面向连接的、可靠的、基于字节流的协议 UDP是无连接的、不可靠的、基于数据报的协议。
| 对比维度 | TCP (传输控制协议) | UDP (用户数据报协议) |
|---|---|---|
| 连接状态 | 面向连接 (类似打电话:先拨号、接通、再通话) | 无连接 (类似寄信:只管写地址寄出,不管对方是否准备好) |
| 可靠性 | 可靠传输 (确认机制、重传机制、保证数据完整有序到达) | 不可靠传输 (尽力而为,不确认、不重传,可能丢包、乱序) |
| 数据边界 | 字节流 (没有明确边界,就像流水,可能粘包) | 数据报 (有明确边界,每个包独立发送,不会粘包) |
| 传输效率 | 较低 (因为需要建立连接、确认、重传等开销) | 较高 (没有额外开销,只是简单封装发送) |
| 速度 | 较慢 | 较快 |
| 拥塞控制 | 有 (会根据网络状况调整发送速率,避免拥塞) | 无 (应用层发多少,就原样发多少) |
| 报文头大小 | 20-60字节 | 8字节 |
| 一对一/多 | 一对一 (主要支持点对点) | 一对一、一对多、多对多 (支持单播、组播、广播) |
从连接状态看:
TCP:通信前必须通过“三次握手”建立连接。通信结束后要通过“四次挥手”释放连接,这确保了双方都是活跃且准备就绪的状态;
UDP:不需要建立任何连接,发生数据前不需要与对方协商,自己想发就发,直接就把数据包发送出去,对方是否在线,能否收到都无所谓。只管自己发送;
从可靠性看:
TCP:
- 确认应答:收到数据后,接收方会回复确认;
- 超时重传:发送方发出数据后,如果长时间未收到确认,就会重新发送;
- 数据排序:如果数据包乱序表达,TCP会重新排序后再交给应用层;
- 流量控制:根据接收方能力调整发送速度,防止对方处理不过来
- 校验和:检测数据是否损坏
UDP:只提供一个简单的校验和(可选,在IPv4下甚至可以不校验)。如果发生丢包、乱序、重复,UDP一概不管,直接交给应用层处理;
从数据边界看:
TCP:是“流式”协议。应用程序发三次“Hello”,对方可能一次性收到“HelloHelloHello” —— 这就是“粘包”。应用层需要自己设计边界(如添加分隔符或固定长度)。
UDP:是“报文”协议。应用程序发一个包,对方就收到一个完整的包,边界清晰。不会出现粘包。
从传输方式看:
TCP:一对一,一个连接只能有两个端点;
UDP:支持单播(一对一)、组播(一对多)、广播(一对所有)。这在视频会议、局域网服务发现等场景很有用。
什么时候用TCP?
需要数据绝对可靠,完整,有序的场景,可以容忍一定的延迟;
- 网页浏览 (HTTP/HTTPS)
- 电子邮件 (SMTP/POP3/IMAP)
- 文件传输 (FTP)
- 数据库连接 (MySQL/PostgreSQL)
- 远程登录 (SSH/Telnet)
什么时候用UDP?
追求实时性和速度,可以容忍偶尔的数据丢失和乱序;
- 实时音视频 (视频通话、直播、在线游戏) —— 丢失一帧图像不影响观看,但延迟高了就会卡顿;
- 域名解析 (DNS) —— 查询请求很小,一次请求一次回复,不需要建立连接;
- 网络时间同步 (NTP)
- 局域网服务发现 (DHCP、广播通信)
- VPN隧道 (部分VPN基于UDP,以提高穿透性和速度,例如WireGuard)
http与https的区别?
HTTP 是明文传输,HTTPS 是加密传输。HTTPS 可以理解为 HTTP + 安全层(SSL/TLS)
从安全性看:
HTTP:数据明文传输,中间节点(路由器、运营商等)可以轻易看到传输的内容,比如你填写的密码、银行卡号等,容易被窃听和篡改。 HTTPS:对传输数据加密,即使被拦截,黑客看到的是乱码,无法读取。同时能验证服务器身份,防止被钓鱼网站欺骗。
从默认端口看: HTTP:80 HTTPS:443
从速度与性能看:
HTTP:无需加密解密,速度稍快。
HTTPS:需要加密解密和证书验证,首次连接稍慢。但现代协议(如 HTTP/2)强制要求 HTTPS,多路复用等技术反而能提升整体性能。
是否需要申请证书:
HTTP:不需要
HTTPS:需要向CA机构申请SSL/TLS证书(有免费和付费两种)
浏览器显示看:
HTTP:地址栏显示 ⚠️不安全 或灰色锁(Chrome等会明确标记)
HTTPS:显示 🔒安全锁。付费高级证书还会显示企业名称(EV证书)
对普通用户:涉及登录、支付、填隐私信息时,务必确认是 HTTPS,并留意浏览器是否有安全锁标志;
对网站主:强烈建议升级 HTTPS。Google 等搜索引擎会给予 HTTPS 网站更高排名,且 HTTP 页面会被标记为“不安全”影响用户信任。
OSI是什么?
OSI 是 Open Systems Interconnection(开放系统互联)的缩写。它通常指代 OSI模型(OSI Model),这是一个由国际标准化组织(ISO)制定的网络通信概念框架。
简单来说,它是一个将计算机网络通信过程划分为 7个层次 的参考模型。从下到上分别为:
- 物理层:传输比特流(0和1),定义线缆、接口、电压等物理规格。
- 数据链路层:在相邻节点间传输数据帧,负责错误检测和流量控制(如以太网、Wi-Fi)。
- 网络层:进行路由选择和地址管理,实现跨网络的数据包传送(如IP协议)。
- 传输层:提供端到端的可靠或不可靠传输,负责分段、重组和端口寻址(如TCP、UDP)。
- 会话层:建立、管理和终止应用程序之间的会话(如NetBIOS)。
- 表示层:数据格式转换、加密解密、压缩解压缩(如SSL/TLS、JPEG)。
- 应用层:直接为用户提供网络服务的接口(如HTTP、FTP、SMTP)。
为什么重要?
- 标准化:让不同厂商的软硬件能互相通信。
- 模块化:将复杂问题分解为7个独立子问题,便于开发和排错。
- 教学工具:学习网络原理的经典模型(虽然实际互联网主要遵循更简化的 TCP/IP模型)
OSI是逻辑理论模型,而TCP/IP是实际应用协议族。很多人说“OSI七层”,但网络实际运行更多参考TCP/IP四层/五层模型。
cookie session token解析:
这三者都是用来解决HTTP无状态问题的工具(HTTP协议本身不记得你是谁)
- Cookie: 客户端(浏览器)的小本本,由服务器下发,浏览器自动携带
- Session: 服务端内存/数据库里的档案柜,记录用户详细信息
- Token: 客户端的身份证,无状态,服务器只负责验证真伪;
1. Cookie
本质: 服务器发给客户端的一个小文本(key=value),浏览器会自动存储,并在下次请求时自动携带。
核心特性:
- 自动携带: 只要域名符合规则,浏览器自己就把Cookie带过去了。
- 大小限制: 通常每个域名下最多存4KB。
- 安全属性: 有
HttpOnly(禁止JS读取,防XSS)、Secure(仅HTTPS发送)、SameSite(防CSRF)等。
典型场景: 会话标识(sessionId)、记住用户偏好(语言、主题)。
2. Session
本质: 服务器为了记住用户状态,在服务器内存或数据库中开辟的一块存储空间。
工作机制(基于Cookie实现):
- 用户登录成功,服务器在内存中创建一个
Session对象(包含用户ID、过期时间等)。 - 服务器生成一个唯一的
SessionID。 - 服务器通过
Set-Cookie把SessionID发给客户端保存。 - 下次请求,浏览器自动带上
Cookie: sessionId=xxx。 - 服务器拿到ID,去仓库里查找对应的用户数据。
核心特性:
- 有状态: 服务器必须存着这份数据。
- 安全: 真实数据(用户名、权限)存在服务器,客户端只有一个乱码ID。
- 缺点: 在分布式/集群环境下,多个服务器之间需要共享Session(存到Redis),否则用户第二次请求被路由到另一台机器,会丢失登录状态。
3. Token
本质: 一串经过加密算法生成的字符串(通常是JWT:JSON Web Token),包含用户信息和签名。
工作机制(无状态):
- 用户登录成功,服务器生成一个Token(比如:
xxxx.yyyy.zzzz)。 - 服务器把Token返回给客户端(通常在响应体里)。
- 客户端收到后,手动存储(
localStorage或Cookie)。 - 下次请求,客户端手动在请求头里带上:
Authorization: Bearer <token>。 - 服务器收到Token,不依赖存储,直接通过签名算法验证Token是否被篡改,并从中解码出用户信息。
核心特性:
- 无状态: 服务器不需要存任何东西(只要密钥不泄露)。验证通过即信任。
- 自包含: Token里直接包含了用户ID、过期时间等信息(明文部分Base64解码可见,不要存密码)。
- 跨平台: 非常适合移动端App(没有Cookie概念)和微服务、跨域场景。
三者的核心区别对比
| 维度 | Cookie | Session | Token |
|---|---|---|---|
| 存储位置 | 客户端浏览器 | 服务器内存/Redis/数据库 | 客户端(localStorage/Cookie) |
| 状态性 | 辅助实现状态 | 有状态(服务器存数据) | 无状态(服务器只验签名) |
| 容量 | 小(4KB) | 无限制(只在服务器内存) | 比Cookie大(几百到几千字节) |
| 安全风险 | 容易被截获(XSS/CSRF) | 依赖Cookie安全属性 | 一旦泄露,任意地方可用(直到过期) |
| 注销/失效 | 清除Cookie | 删除服务器Session数据 | 较难(需加黑名单,打破无状态) |
| 适用场景 | 传统Web、偏好存储 | 传统Web单体应用 | 前后端分离、App、微服务、SSO |
常见误区与最佳实践
-
误区:Cookie 不安全,Token 安全。
- 如果Token存在
localStorage,容易受XSS攻击。 - 如果Token存在
Cookie里且未设置HttpOnly,也容易受XSS攻击。 - 最佳实践: 将Token放在
HttpOnly+Secure+SameSite=Strict的Cookie中传输,可以同时防御XSS和CSRF。
- 如果Token存在
-
误区:Session 只能用在浏览器。
- 理论上任何支持Cookie的HTTP客户端都可以,但App手动管理Cookie麻烦,所以App更爱用Token。
-
现实趋势:
- 传统内部管理系统: 依然大量使用 Session。
- 现代前后端分离项目 / App / 微服务: 使用 Token (JWT)。
- 终极安全方案: 使用 双重Token (短效Access Token + 长效Refresh Token),配合HttpOnly Cookie。
一句话总结
- Cookie 是运输工具(装东西的容器)。
- Session 是服务器上的档案柜,钥匙(SessionID)放在Cookie里运输。
- Token 是防伪身份证,所有信息都写在身份证上,服务器只需查验真伪,无需翻档案柜。
Token鉴权流程:
Token鉴权是目前前后端分离、移动端App以及微服务架构中最主流的身份认证方式。它解决了传统Session鉴权在分布式环境下扩展性差、移动端不兼容等痛点。
整个过程类似于安检登机:换登机牌(Login)、出示证件(Verify)、验证放行(Access)。
详细步骤拆解:
第一阶段:登录认证(签发Token)
-
客户端发送凭证:用户输入账号密码,客户端通过POST请求发送给后端的登录接口(如
/api/login)。 -
服务器校验:后端校验账号密码是否正确。
-
生成Token:
- 校验通过后,服务器生成一个Token字符串。
- 常见载体:JWT(JSON Web Token),它包含三部分:Header(头部)、Payload(存放用户ID、过期时间等)、Signature(签名防篡改)。
-
返回Token:服务器将Token返回给客户端。通常返回两个:
access_token:短有效期(如2小时),用于日常请求。refresh_token:长有效期(如7天),用于重新获取access_token(可选但推荐)。
第二阶段:携带Token访问资源
-
客户端存储:客户端收到Token后,存储在 localStorage、SessionStorage(Web)或 Keychain(App)中。
-
构造请求头:客户端在后续调用业务接口(如获取用户信息、下单)时,必须在HTTP请求的 Header 中携带Token。
-
标准字段:
Authorization -
格式:
Bearer <Token字符串> -
示例:
GET /api/user/info HTTP/1.1 Host: example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
-
-
服务器验证:业务接口接收到请求后,不会立即处理业务,而是先执行Token验证:
- 是否携带:检查Header中是否有Authorization字段。
- 签名是否合法:防止Token被篡改。
- 是否过期:检查Payload中的过期时间(exp)。
- 是否有效(可选):在黑名单中(用户注销后)或Redis中存在。
-
返回结果:
-
验证通过:解析Token中的用户ID(如
user_id),执行具体业务逻辑,返回数据。 -
验证失败:
- Token过期:返回 401 Unauthorized 状态码。
- Token无效/签名错误:返回 403 Forbidden。
-
第三阶段:自动刷新Token(解决过期问题)
这是提升用户体验的关键。客户端不会让用户重新登录,而是静默刷新。
- 客户端请求业务接口,收到 401 状态码。
- 客户端判断是Token过期,立即调用 刷新Token接口(如
/api/refresh),并携带refresh_token。 - 服务器校验
refresh_token是否有效且未过期。 - 如果有效,服务器生成**新的
access_token**返回给客户端(有时也会刷新refresh_token)。 - 客户端用新Token 重试刚才失败的原始业务请求。
测试中的关键校验点
在设计Token鉴权的测试用例时,必须覆盖以下场景:
| 测试场景 | 操作方法 | 预期结果 |
|---|---|---|
| 正常访问 | 登录后,在Header中带上正确Token请求接口 | 返回200,业务数据正确 |
| 无Token | 请求Header中不带Authorization字段 | 返回401,提示“未认证” |
| Token错误 | Token随意改一个字符 | 返回403,提示“签名无效”或“Token无效” |
| Token过期 | 等待access_token过期(或手动修改过期时间)后再请求 | 返回401,提示“Token已过期” |
| Token为空 | Authorization: Bearer 后面为空 | 返回401 |
| 格式错误 | 写成Authorization: Bearer123 (无空格) 或 直接传Token不加Bearer | 返回401 |
| 用户注销 | 用户点击退出登录后,再次使用旧Token请求 | 返回401,且Token被加入黑名单 |
| 越权访问 | 用户A的Token,去请求用户B的订单详情(/order/456,456属于B) | 返回403,提示“无权限访问他人资源” |
| 刷新Token | access_token过期,调用刷新接口传入refresh_token | 返回新的access_token |
| refresh_token过期 | 使用过期的refresh_token刷新 | 返回401,需跳转登录页 |
| 并发请求 | 同时发送多个业务请求,且都因Token过期而刷新 | 只刷新一次Token,其他请求排队或重试,避免重复刷新 |
测试中常见的误区
-
只测了登录,没测鉴权:很多新手只测登录接口返回Token是否正确,但忘了测试其他业务接口带上错误的Token会怎样。
-
混淆了401和403:
- 401:没登录或登录过期 → 客户端应该跳转登录。
- 403:已登录但没权限(如普通用户访问管理员接口)→ 客户端应提示“无权限”。
-
忽略刷新Token的并发问题:如果一个页面同时发起了10个请求,都因Token过期返回401,可能会触发10次刷新Token请求,导致后端压力或Token被覆盖。好的设计应该是第一个请求去刷新,后续请求排队等待。
-
Token没有设置过期时间:非常危险!一旦Token泄露,攻击者可以永久使用。测试时检查Payload里是否有
exp字段。
如何快速构造测试场景?
- 获取Token:调用登录接口,从响应中提取Token。
- 修改Token:在在线JWT网站(如jwt.io)上修改Payload里的过期时间,生成新的Token进行测试。
- 模拟过期:如果后端不支持动态修改过期时间,可以让开发提供一个“短过期时间(如1分钟)”的测试环境接口。
- 工具设置:在Postman/Apifox中,将Token设置为环境变量,所有接口自动读取,避免每个用例手动粘贴。
接口文档的组成:
- 封面:封面最好是本公司规定的封面,有logo、内容标题、版本号、公司名称、文档产生日期;
- 修订历史:包括版本、修订说明、修订日期、修定人、审核时间和审核人等
基本信息:
- 接口名称:如“获取用户详情”、“创建订单详情”;
- 接口路径:URL,例如:chat.deepseek;
- 请求方法:GET POST PUT DELETE等;
- 接口描述:简要说明接口的功能(如:“用于用户登录,返回token”)
- 认证方式:是否需要登录?如何传递凭证?(例如:
Bearer Token、JWT、AppId/Secret)
请求参数:调用接口时需要发送的数据;核心部分
- 参数名称:如username 或password
- 位置: Path:路径参数(如
/user/{id}中的id);Query:URL 问号后的参数(如?page=1);- Header:请求头(如Content-Type、Authorization);Body:请求体(常用于 POST/PUT) - 类型:string、integer、boolean、array、object、file。
- 必填性:是(Required) / 否(Optional)
- 示例值:给测试和前端一个具体的参考(如
"13800000000") - 描述/约束:长度限制、取值范围、格式要求(如
正则表达式)
请求示例:一个可以直接拿来用的样本(包含完整的URL,Header示例,Body示例)
示例:
POST /api/order/create HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer {token}
{
"productId": 1001,
"quantity": 2
}
响应数据:接口返回的数据结构,这是测试断言(校验点)的依据
- 状态码: 如 200(成功)、400(参数错误)、401(未授权)、500(服务器错误)或业务状态码:很多接口会返回自定义的
code字段(如code:0代表成功,code:1001代表用户名不存在)。 - 响应体结构: 字段名、类型、含义 3.** 返回示例:** 成功时的返回样例,以及常见失败时的返回样例;
示例:
{
"code": 0,
"message": "success",
"data": {
"userId": 123,
"userName": "张三",
"token": "eyJhbGciOiJIUzI1NiIs..."
}
}
错误码说明:
| 业务码 (code) | HTTP状态码 | 含义 | 解决方案 |
|---|---|---|---|
| 1001 | 400 | 用户名已存在 | 更换用户名 |
| 1002 | 401 | Token 已过期 | 重新登录 |
| 2001 | 403 | 余额不足 | 请充值 |
注意事项/备注: 补充说明特殊逻辑,避免测试漏测
- 幂等性: 是否支持重复请求?是否需要前端传递幂等键?
- 限流策略: 每秒、每分限制请求次数(如100次、分钟)
- 异步处理: 是同步返回结果,还是返回任务 ID 需要轮询结果?
- 依赖关系:调用本接口前是否需要先调用登录接口?
- 环境差异:测试环境与生产环境的回调地址是否不同?
变更记录: 接口是会变动的,必须有历史记录。
- 版本号:v1.0, v1.1, v2.0。
- 修改日期:2023-10-01。
- 修改内容:参数
age由 int 改为 string / 新增字段xxx。 - 修改人:方便追溯
接口用例的组成:
- 用例ID:唯一编号,便于追溯和管理(如
TC_LOGIN_001) - 用例/接口名称:清晰描述测试目的(如“用户登录-正确账号密码-登录成功”)
- 优先级:P0(冒烟)、P1(高)、P2(中)、P3(低)
- 关联需求::对应的Jira、TAPD或PRD文档ID
- 前置条件:执行该用例前必须满足的状态
- 请求信息:请求URL:api.example.com/v1/user/log… ;请求方法:GET、POST、PUT、DELETE等;请求头(Headers) :
Content-Type: application/json、Authorization: Bearer xxx、Cookie;请求参数/体(Body) - 预期结果:判断用例是否通过的唯一标准;包含响应状态:HTTP状态码(200、201、400、401、500);响应体数据:必含字段:
code(业务码,如0代表成功)、message(提示信息);核心数据:user.id:10001;order.status:“PAID”;数据结构:返回的list长度应为10;total应为大于0的整数。 - 返回结果:实际返回的结果
- 后置处理:执行完接口后需要做的清理或提取工作(自动化中尤其重要);如数据提取: 从响应中提取
orderId,供后续“支付”接口使用;数据清理:删除刚才创建的测试用户,恢复数据库状态,避免影响其他用例