he4rt/reqxide
GitHub: he4rt/reqxide
一款基于 PHP 的 TLS/HTTP 指纹识别与浏览器仿真库,解决标准 HTTP 客户端指纹易被反机器人系统识别的问题。
Stars: 35 | Forks: 0
# Reqxide
PHP TLS/HTTP 指纹识别库,用于浏览器仿真。
[](https://github.com/he4rt/reqxide/actions)
[](https://packagist.org/packages/he4rt/reqxide)
[](https://packagist.org/packages/he4rt/reqxide)
Reqxide 为 PHP 带来 TLS 和 HTTP/2 指纹识别功能。它模拟真实浏览器的指纹(Chrome、Firefox、Safari、Edge、OkHttp),使你的 HTTP 请求看起来与真实浏览器流量完全一致。构建在 `curl_impersonate` 之上,提供与 PSR-18 兼容的客户端,并实现透明的浏览器仿真。
移植自 Rust 的 [wreq](https://github.com/nickel-org/wreq)。
## 为什么?
像 Cloudflare、Akamai 和 DataDome 这样的反机器人系统会通过 TLS 握手和 HTTP/2 帧进行指纹识别,以区分机器人和真实浏览器。标准的 PHP HTTP 客户端(Guzzle、Symfony HttpClient)会产生类似机器的指纹,会被立即拦截。
Reqxide 通过控制以下方面来解决这个问题:
- **TLS ClientHello** —— 密码套件、椭圆曲线、签名算法、扩展、ALPN、GREASE、ECH
- **HTTP/2 SETTINGS** —— 帧顺序、窗口大小、伪头部顺序、流优先级
- **头部顺序和大小写** —— 浏览器以特定顺序和特定大小写发送头部
结果:你的请求会产生与真实浏览器相同的 JA3/JA4 指纹。
## 安装
```
composer require he4rt/reqxide
```
## 快速开始
```
use Reqxide\Client;
use Reqxide\Emulation\Browser;
$client = Client::builder()
->emulation(Browser::Chrome131)
->build();
$response = $client->get('https://example.com')->send();
echo $response->getStatusCode(); // 200
echo (string) $response->getBody();
```
## 用法
### 浏览器仿真
选择一个浏览器配置文件。每个配置文件都捆绑了真实浏览器使用的确切 TLS 配置、HTTP/2 设置、默认头部和头部排序。
```
use Reqxide\Client;
use Reqxide\Emulation\Browser;
// Chrome (latest)
$client = Client::builder()->emulation(Browser::Chrome131)->build();
// Firefox
$client = Client::builder()->emulation(Browser::Firefox136)->build();
// Safari (macOS, iOS, iPad)
$client = Client::builder()->emulation(Browser::Safari18)->build();
$client = Client::builder()->emulation(Browser::SafariIOS18)->build();
// Edge (Chromium-based, different sec-ch-ua)
$client = Client::builder()->emulation(Browser::Edge131)->build();
// OkHttp (Android HTTP client)
$client = Client::builder()->emulation(Browser::OkHttp5)->build();
```
### 发起请求
Reqxide 实现了 PSR-18(`ClientInterface`)并提供便捷方法:
```
// Convenience API
$response = $client->get('https://api.example.com/users')->send();
$response = $client->post('https://api.example.com/users')
->json(['name' => 'Daniel', 'email' => 'daniel@he4rt.com'])
->send();
// With headers and auth
$response = $client->get('https://api.example.com/me')
->bearerToken('your-token')
->header('X-Custom', 'value')
->send();
// Form data
$response = $client->post('https://example.com/login')
->form(['username' => 'admin', 'password' => 'secret'])
->send();
// Query parameters
$response = $client->get('https://api.example.com/search')
->query(['q' => 'reqxide', 'page' => '1'])
->send();
// PSR-18 standard (drop-in for any PSR-18 consumer)
$response = $client->sendRequest($psrRequest);
```
### 代理支持
支持 HTTP、HTTPS、SOCKS4 和 SOCKS5,并可选认证:
```
use Reqxide\Proxy\Proxy;
$client = Client::builder()
->emulation(Browser::Chrome131)
->proxy(Proxy::http('45.38.89.88:6023'))
->build();
// SOCKS5
$client = Client::builder()
->emulation(Browser::Chrome131)
->proxy(Proxy::socks5('127.0.0.1:1080'))
->build();
// With authentication
$proxy = new Proxy(
scheme: ProxyScheme::Http,
host: 'proxy.example.com',
port: 8080,
username: 'user',
password: 'pass',
);
```
### Cookie 持久化
```
use Reqxide\Cookie\CookieJar;
// Automatic cookie jar
$client = Client::builder()
->emulation(Browser::Chrome131)
->cookieStore(true)
->build();
// Shared cookie jar across clients
$jar = new CookieJar();
$client = Client::builder()
->emulation(Browser::Chrome131)
->cookieStore($jar)
->build();
// Cookies persist across requests automatically
$client->get('https://example.com/login')->form([...])->send();
$client->get('https://example.com/dashboard')->send(); // sends session cookie
```
### 重定向与重试
```
use Reqxide\Redirect\RedirectPolicy;
use Reqxide\Retry\RetryPolicy;
$client = Client::builder()
->emulation(Browser::Chrome131)
->redirect(RedirectPolicy::limited(10)) // follow up to 10 redirects
->retry(RetryPolicy::default()) // retry 5xx, max 2 attempts, 20% budget
->build();
// Disable redirects
$client = Client::builder()
->emulation(Browser::Chrome131)
->redirect(RedirectPolicy::none())
->build();
// Custom retry logic
$client = Client::builder()
->emulation(Browser::Chrome131)
->retry(RetryPolicy::custom(
classifier: fn($req, $res, $err) => $res?->getStatusCode() === 429,
maxRetries: 5,
baseDelayMs: 1000,
))
->build();
```
### 客户端配置
```
$client = Client::builder()
->emulation(Browser::Chrome131)
->proxy(Proxy::socks5('127.0.0.1:1080'))
->timeout(30) // seconds
->connectTimeout(10) // seconds
->cookieStore(true) // enable cookie jar
->redirect(RedirectPolicy::limited(10)) // follow redirects
->retry(RetryPolicy::default()) // retry on failure
->verify(false) // disable SSL verification
->defaultHeaders(['X-App' => 'myapp']) // extra headers on every request
->build();
```
## 架构
```
User Code
|
v
+---------------------------------+
| PSR-18 Client (Reqxide\Client) |
| sendRequest(RequestInterface) |
+---------------------------------+
|
v
+---------------------------------+
| Middleware Pipeline |
| Cookie -> Redirect -> Retry -> |
| Compression -> Transport |
+---------------------------------+
|
+--------+---------+
v v v
FFI ext/curl Process
(full) (partial) (binary)
| | |
v v v
libcurl-impersonate
```
**三种传输后端:**
| 传输方式 | 指纹识别控制 | 依赖 |
|-----------|-------------------|----------|
| `FfiTransport` | 完整(TLS + HTTP/2 + 头部) | PHP FFI + libcurl-impersonate |
| `CurlTransport` | 部分(TLS 密码、曲线、ALPN) | ext-curl |
| `ProcessTransport` | 完整(通过二进制文件) | curl-impersonate 二进制文件 |
`TransportFactory::create()` 会自动检测最佳可用传输方式。
## 框架集成
### Guzzle
```
use Reqxide\Adapter\Guzzle\GuzzleHandlerAdapter;
use Reqxide\Emulation\Browser;
$handler = new GuzzleHandlerAdapter(Browser::Chrome131);
$guzzle = new \GuzzleHttp\Client([
'handler' => \GuzzleHttp\HandlerStack::create($handler),
]);
$response = $guzzle->get('https://example.com');
```
### Laravel
```
// In a ServiceProvider
use Reqxide\Client;
use Reqxide\Emulation\Browser;
$this->app->singleton(Client::class, fn () =>
Client::builder()->emulation(Browser::Chrome131)->build()
);
// Usage
$client = app(Client::class);
$response = $client->get('https://api.example.com/data')->send();
```
### Symfony
```
use Reqxide\Adapter\Symfony\SymfonyClientAdapter;
use Reqxide\Emulation\Browser;
$client = new SymfonyClientAdapter(Browser::Chrome131);
$response = $client->request('GET', 'https://example.com', [
'headers' => ['Accept' => 'application/json'],
]);
```
## 支持的浏览器
| 浏览器 | 版本 | 关键差异 |
|---------|----------|-----------------|
| Chrome | 128、129、130、131 | 130+ 支持 X25519MLKEM768(后量子),启用 GREASE |
| Firefox | 135、136 | 不支持 GREASE、FFDHE 曲线、Sec-Fetch-* 头部、不同的伪头部顺序 |
| Safari | 18(macOS、iPad、iOS) | 不支持 GREASE、无 ECH、最小化头部、不同的 HTTP/2 窗口大小 |
| Edge | 131 | 基于 Chromium + Edge 特定的 User-Agent 和 sec-ch-ua |
| OkHttp | 4、5 | 仅 HTTP/1.1、无浏览器头部、Android 客户端指纹 |
### 指纹识别精度
每个配置文件控制完整的 TLS/HTTP/2 指纹:
```
Chrome 131:
JA3: 9e2da15d3e1b6931c6fbaa3f9ac9cd89
JA4: t13d913h2_f91f431d341e_882d495ac381
HTTP: h2 | Ciphers: 9
Firefox 136:
JA3: bdc242f0548bc1fcc45d12edc713b8e1
JA4: t13d1513h2_8daaf6152771_882d495ac381
HTTP: h2 | Ciphers: 15
```
## 工作原理
当你选择 `Browser::Chrome131` 时,reqxide 会配置:
**TLS 层:**
- 密码套件按 Chrome 的确切顺序(9 个密码)
- 椭圆曲线:X25519MLKEM768、X25519、P-256、P-384
- 签名算法:8 个算法,按 Chrome 的顺序
- 密钥共享:X25519MLKEM768 + X25519
- 扩展:GREASE、ECH GREASE、排列后的扩展、OCSP 签名、时间戳
**HTTP/2 层:**
- SETTINGS 帧:头部表 65536,禁用推送,最大流 1000,窗口 6MB,最大帧 16384,最大头部列表 262144
- 伪头部顺序:`:method`、`:authority`、`:scheme`、`:path`
- 连接窗口:15663105 字节
**头部:**
- 默认浏览器头部(sec-ch-ua、User-Agent、Accept、Accept-Encoding、Accept-Language)
- 头部顺序与 Chrome 发送顺序完全匹配
- 大小写保留(sec-ch-ua,而非 Sec-Ch-Ua)
## 测试
```
# 完整质量套件 (lint + phpstan + pest + rector)
composer test
# 单独检查
composer test:lint # Laravel Pint formatting
composer test:types # PHPStan level max
composer test:unit # Pest with 100% coverage
composer test:type-coverage # 100% type coverage
composer test:refactor # Rector dry-run
# 运行特定测试
./vendor/bin/pest tests/Unit/Tls/TlsOptionsTest.php
./vendor/bin/pest --filter="Chrome 131"
# 集成测试(需要网络)
./vendor/bin/pest --group=integration
```
## 项目结构
```
src/
Client.php # PSR-18 ClientInterface
ClientBuilder.php # Fluent builder
RequestBuilder.php # Per-request builder (get, post, json, form...)
Contract/ # Interfaces (Transport, CookieStore, Profile, Redirect, Retry)
Emulation/ # Browser enum, Profile, Catalog (Chrome, Firefox, Safari, Edge, OkHttp)
Tls/ # TLS options, enums (ciphers, curves, sigalgs, versions)
Http2/ # HTTP/2 options (settings, pseudo-headers, priorities)
Http1/ # HTTP/1 options (header ordering)
Transport/ # CurlTransport, FfiTransport, ProcessTransport, TransportFactory
Middleware/ # Pipeline, Cookie, Redirect, Retry, Compression
Cookie/ # CookieJar (RFC 6265), Cookie value object
Proxy/ # Proxy value object, ProxyScheme enum
Redirect/ # RedirectPolicy (limited, none, custom)
Retry/ # RetryPolicy, RetryBudget (token bucket)
Adapter/ # Guzzle, Laravel, Symfony integrations
Exception/ # PSR-18 compliant exception hierarchy
```
## 致谢
- 移植自 [wreq](https://github.com/nickel-org/wreq)(Rust)
- 基于 [curl-impersonate](https://github.com/lwthiker/curl-impersonate)
- 由 [He4rt 开发者](https://github.com/he4rt) 构建
## 许可证
Reqxide 是开源软件,采用 **[MIT 许可证](https://opensource.org/licenses/MIT)** 授权。
标签:BeEF, Browser Profile, Chrome, ClientHello, composer, cURL, Edge, Emulation, ffuf, Firefox, HTTP/2, HTTP指纹, JA3, JA4, OkHttp, OpenVAS, PHP, PSR-18, Radare2, Safari, TLS指纹, TLS握手, 反反爬, 反机器人, 多架构支持, 库, 应急响应, 开源, 浏览器仿真, 爬虫, 网络请求, 网络调试, 自动化, 请求伪装