明月桥 2025-06-10 15:04 采纳率: 0%
浏览 5

Netty代理服务器导致Android模拟器(Flutter App)登录失败,而HttpCanary代理成功,抓取特定Cookie时遇到问题

我在 Windows 11 上开发了一个基于 Netty 的 HTTP/HTTPS 代理服务器(v4.1.x),目标是在 MuMu 模拟器(Android)上抓取一个特定 Flutter 应用的网络请求中的 Cookie。该应用使用索尼的第三方登录流程(点击登录后弹出索尼WebView登录,登录成功后WebView关闭,App获取凭证完成登录)。
​我的设置:​​

将 MuMu 模拟器的全局 HTTP 和 HTTPS 代理设置为我的主机 IP 地址 192.168.1.108 和端口 8081。
为了捕获 Flutter App 可能通过 IP 地址进行的直接连接,我使用 iptables 规则(在模拟器内部?或者在主机上?​​请确认iptables设置位置​)将所有来自模拟器的 IP 流量(非特定端口)重定向到 192.168.1.108:8081。
我的 Netty 代理成功处理了模拟器上普通的 HTTP/HTTPS 浏览流量(验证过)。
对比了登录过程中的关键响应:当 Netty 代理打开时,App 最终会收到一个 302 重定向响应;当代理关闭​(或直接连接)时,App 也收到一个相同的​ 302 响应(响应头、状态码、Location 我都对比过,完全一致)。

核心问题:​​

当使用我自己的 Netty 代理时,该 App 在索尼登录流程后​​登录失败**​(无法获取到最终的鉴权数据)。
当关闭 Netty 代理​(直连)时,登录成功。
当在模拟器内部使用 HttpCanary(作为本地代理)​​ 时,App 登录也成功​(且我能看到目标请求和Cookie)。

​矛盾点:​​ 如果 Netty 代理和最终的无代理/HttpCanary 环境都收到了完全相同的 302 响应(我认为是登录成功的关键一步),​为什么只有在使用我的 Netty 代理时 App 才登录失败?​​ 它似乎对代理存在额外的、隐藏的依赖或限制。

补充细节:netty服务器有时候会打印/badrequest日志,是netty无法解析导致的,用httpcanary抓包登录流程则不会,我不确定是不是这个问题,我没有找到产生/badrequest的原因。

netty服务器重定向的302如下:


```java
HTTP/1.1 302 Moved Temporarily
Server: nginx
Content-Length: 0
X-Psn-Request-Id: 5b7bbc757e54bcc59c3e309f97f36962
X-Psn-Correlation-Id: b5a6eb55-c518-4879-accf-d74de2bdcd94
X-RequestId: 5b7bbc757e54bcc59c3e309f97f36962
X-CorrelationId: b5a6eb55-c518-4879-accf-d74de2bdcd94
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
Location: com.mlb.psn.app://redirect/?code=v3.t9Mczq&cid=b5a6eb55-c518-4879-accf-d74de2bdcd94
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Date: Fri, 06 Jun 2025 18:53:49 GMT
Connection: keep-alive
Set-Cookie: bm_sz=B7501ED00BA0FFCAC7BFDB859CB309CD~YAAQqffVF5p/1iiXAQAA6ZiXRhyrCEz5YqXI7fAemlL2vA5sPORdRCCLcGKZpfz0fQzQhNuU1Iy+mZ387kFBzlvIgLUA6qwqBbByc88z4DLCjftrCBqDKVZCauF8NLSVRjNSfdwE4glcFjGXxl1sK44/+iLYV/z/iWFnad2af6Qhwv47YJGZSXHBNdVXOznIhOcJiecHg5WXVSxIuQrquT+9Hub1OXEBeOjOmCo3KiWevPR2LnOyL+tDLfB6W6Cjy5RByD2qtK3Y3Dm6O3UvCuJHzCfJhWv3UvKush6KaciGx6qICmo1Y3rAMcvZGspurRkVj70jarvrEAVgsKAwt1fP8dHFMyHibeL8r+6decSGJ1G2fSpoQwp20yQMtHXkRmAeGhRoncnhywF+eIz+VnUNXqJpOjk4vfkKmG1ldG0m1SizhXV++FMtcHnwcUIqHcmg8iusdisZsiA0bkKrERXCmPlxQU+xQFDw6Gx7OZan/GLpFaTqNMy/0MZY5iCF2Eel+RcsCEE5UhrlOL0T57QNHsX4OzqhdaQOTP9SOYe637v8F5rzlFauei0NVirdQhnd9UdwPhBtvVWEOZQ=~3290936~3687985; Domain=.sony.com; Path=/; Expires=Fri, 06 Jun 2025 19:20:14 GMT; Max-Age=1585


httpcanary的重定向抓包如下:
HTTP/1.1 302 Moved Temporarily
Server: nginx
Content-Length: 0
X-Psn-Request-Id: 972740184ce63b0cabef69d79198dcac
X-Psn-Correlation-Id: 1f9f236c-31ea-40d1-b43a-6fffc2866cca
X-RequestId: 972740184ce63b0cabef69d79198dcac
X-CorrelationId: 1f9f236c-31ea-40d1-b43a-6fffc2866cca
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
Location: com.mlb.psn.app://redirect/?code=v3.6mJ92x&cid=1f9f236c-31ea-40d1-b43a-6fffc2866cca
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Date: Fri, 06 Jun 2025 19:06:40 GMT
Connection: keep-alive
Set-Cookie: bm_sz=A332E979CC0199FAC6C582D3109A7B18~YAAQj2rRF0f2lzyXAQAAVFyjRhyto6LKOPtRfPKVaAH4GWzGmzfyalEAqOhsd3bfX3LjrQouq0KUKR1DJTv89BwydT6Rp/AhllaCPa6yEg4xzpCsua9h7wZDALyQ66+kBD33NIw8Pj6oMOILzH+6QKm+H4KgMYjW0nhmIpv3KhccxEULBc9sXq/AFApivWp1RbiA6BnuhthCLzq0ZN8FF6zO7HxvwgjOb6AY0XjQMQ67Ca+a2fPiU6H+O+K8Oq31sdcFxVDaNlHgAC4S4Y+ntgmpjRsJe7QrFHfZbAjQgcD5gUScAfvS47+OgTmP0O+Q/0xmjdI/Me1azvAn7VE+eyxV2Qo50zbLQ6w8oFmTBULxn9kYK4ahUQZ16FUGOZSt8zkqCaWLsHsZ8oifgNRrVtXQKANUS2JuC/qa/G7qM129GJfqiTOWbeIfS8SGYt9m76TCWrvIRdk52YRBJySgSj5/tusL1n9SJHrGlf/USW9cMDlsCZa4m4QSAsKgjmqB4JHjAEP9Rd6C4MMIT8B5f8fG3Ru5xz87kI+Wq62tO4k0JfJ/KtNhMwLZxYwkGqheU0WM5rtD0TQvmjC1D1K0J2nT48lhD/uDbjvsFELEaUyO+5s=~3487043~3158597; Domain=.sony.com; Path=/; Expires=Fri, 06 Jun 2025 22:58:49 GMT; Max-Age=13929

```

  • 写回答

5条回答 默认 最新

  • 阿里嘎多学长 2025-06-10 15:06
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    问题分析

    你使用 Netty 开发了一个 HTTP/HTTPS 代理服务器,目标是在 MuMu 模拟器上抓取一个特定 Flutter 应用的网络请求,但是遇到了问题:在使用 Netty 代理服务器时,Android 模拟器上的 Flutter App 登录失败,而使用 HttpCanary 代理服务器时却成功。

    问题解决方案

    1. 检查 Netty 代理服务器的配置是否正确,确保代理服务器正确地将请求转发到目标服务器。
    2. 检查 MuMu 模拟器的网络设置是否正确,确保模拟器可以访问目标服务器。
    3. 使用 Netty 代理服务器的 debug 模式,查看代理服务器是否正确地处理了请求和响应。
    4. 检查 Flutter App 的网络请求是否正确,确保 App 使用了正确的网络请求方式(例如 GET、POST 等)。
    5. 尝试使用 HttpCanary 代理服务器的 debug 模式,查看代理服务器是否正确地处理了请求和响应。

    核心代码

    以下是一个简单的 Netty 代理服务器示例代码,用于转发请求到目标服务器:

    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    public class NettyProxyServer {
        public static void main(String[] args) throws Exception {
            // 创建 EventLoopGroup
            NioEventLoopGroup group = new NioEventLoopGroup();
    
            // 创建 Bootstrap
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new ChannelInitializer<Channel>() {
                        @Override
                        protected void initChannel(Channel ch) throws Exception {
                            // 设置代理服务器的处理逻辑
                            ch.pipeline().addLast(new ProxyHandler());
                        }
                    });
    
            // 绑定端口
            ChannelFuture future = bootstrap.bind(8080).sync();
            future.channel().closeFuture().sync();
        }
    }
    
    class ProxyHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            // 处理请求
            HttpRequest request = (HttpRequest) msg;
            // 将请求转发到目标服务器
            Channel targetChannel = new NioSocketChannel();
            targetChannel.connect("target-server.com", 80);
            targetChannel.writeAndFlush(request);
        }
    }
    

    请注意,这只是一个简单的示例代码,实际实现中可能需要更多的逻辑和配置。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月10日