fix: recover authenticated undergraduate full pages with session guards
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Android 首版验证记录
|
||||
|
||||
当前浏览器诊断细化版为0.7.2+20,验证见 [0.7.2记录](tpschedule-0.7.2-validation.md)。本科接入记录见 [0.7.0记录](tpschedule-0.7.0-validation.md)。下文为首版历史记录。
|
||||
当前完整页面恢复版为0.7.3+21,验证见 [0.7.3记录](tpschedule-0.7.3-validation.md)。本科接入记录见 [0.7.0记录](tpschedule-0.7.0-validation.md)。下文为首版历史记录。
|
||||
|
||||
日期:2026-10-13。测试环境:Flutter 3.47.7 / Dart 3.13.5 / JDK 17;Android 16 API 36,Pixel 7 模拟器,1080×2400。首版版本 0.1.0+1,包 ID com.example.hepan_everyday,最低 Android 7.0(API 24)。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 学校接入状态 · TPSchedule 0.7.2
|
||||
# 学校接入状态 · TPSchedule 0.7.3
|
||||
|
||||
0.7.1真机新日志确认本科认证成功,进入教务页面后有重复脚本错误。0.7.2细化现有日志,记录固定错误类型、已知基础库与样式状态及导出时间;尚未确定实际组件缺失的根因。详见 [0.7.2记录](tpschedule-0.7.2-validation.md)。
|
||||
0.7.2真机日志确认本科认证后缺少公共脚本和样式,框架片段输出规则与WebView请求头行为是高概率原因。0.7.3增加有界的同会话完整页恢复;已通过离线及Android原生验证,仍待校园网真实账号复测。详见 [0.7.3记录](tpschedule-0.7.3-validation.md)。
|
||||
|
||||
0.7.1补充学校浏览器宽视口、第三方Cookie和资源错误诊断,修复本科认证跳转导致读取永久中断的竞态。255项单元测试及Android16原生浏览器测试通过。用户截图中的样式与组件缺失尚需真机复测,不能仅凭测试认定已解决,详见 [0.7.1验证记录](tpschedule-0.7.1-validation.md)。
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# 教务页面缺少公共头部:证据与修复设计
|
||||
|
||||
2026-10-15,TPSchedule 0.7.2+20。本文不包含学生原始HTML、请求凭证或原始日志。
|
||||
|
||||
## 已确认的证据
|
||||
|
||||
用户更正后的日志导出于北京时间15:41:07。15:40:47后,学校认证返回本科系统,读取证据authenticated=true;控制台先后记录reference_error和jquery_missing。原生页面状态为脚本标签2、样式表0、样式链接0,jQuery、Beangle和Require均不存在。这是登录后基础依赖未进入页面的证据,不能用调整课表解析器解决。
|
||||
|
||||
15:31–15:32的空白尝试属于用户后来确认未连接校园网时的记录,应与联网后组件缺失区分。身份认证图片404和此前主文档连接错误不能直接当作15:40教务页面的根因。
|
||||
|
||||
此前用户提供的Chrome导出本科HTML,其head包含多组jQuery、Beangle、Require及CSS依赖。仓库未复制原始附件。
|
||||
|
||||
## 官方源码交叉核对
|
||||
|
||||
1. [Beangle旧Java框架的head.ftl](https://github.com/beangle/beangle3/blob/main/struts/s2/src/main/resources/template/html/head.ftl)以请求头和同名参数是否存在,决定是否输出公共head。判断并非仅比较XMLHttpRequest值;把头改为空字符串并不能据此保证输出head。该规则可以产生正文和少数内联脚本仍在、公共脚本和样式缺失的现象。
|
||||
2. [Chromium的Android WebView网络实现](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc)会在请求尚未显式设置X-Requested-With时添加宿主包名,且注明该自动值对shouldInterceptRequest不可见。因此仅看拦截回调中的请求头也不足以证明线上没有该头。
|
||||
3. [AndroidX WebSettingsCompat文档](https://developer.android.com/reference/androidx/webkit/WebSettingsCompat)说明setRequestedWithHeaderOriginAllowList自1.15.0起失效;当前固定WebView插件依赖的正是AndroidX WebKit1.15.0。不能把该接口当作有效修复,也不应为此偷偷降级插件依赖。
|
||||
|
||||
三者与日志高度吻合,但尚未直接捕获用户手机的线上请求头,也没有获得受影响在线页面的原始响应;该原因仍应标为高概率推断。用户暂不方便USB联调,后续继续文件与可验证的兼容处理。
|
||||
|
||||
## 有界修复设计(用户已确认,2026-10-15)
|
||||
|
||||
目标保持原学校网页登录、验证码、手动选择本科课表及APP读取流程。仅针对已认证而缺少公共依赖的学校页面增加完整页恢复,沿用系统WebView。
|
||||
|
||||
- 学生仍在学校网页输入账号密码和验证码,应用不接管输入。
|
||||
- 对受限制的学校HTTPS只读页面,用同一登录会话请求原地址的完整HTML;该请求不携带触发片段输出的X-Requested-With标记。Cookie只用于原学校域名,不进入日志、反馈或其他服务器。
|
||||
- 读取到完整页面并验证来源、状态、类型及大小后,再交给现有WebView显示。异常、跳转到认证页、页面已变更、退出、取消或超限时不替换当前页面,不导入或清空旧课表。
|
||||
- 不接管验证码、选课、提交表单等POST操作;不放宽HTTPS证书校验,不修改学校安全策略;完整页恢复次数有限,避免循环刷新。
|
||||
- 先以框架同类片段/完整页规则、会话隔离、取消和恶意跳转做回归,再做Android原生验证。真实学校账号复测仍是最终确认,测试通过不能代替该确认。
|
||||
|
||||
用户已明确确认同会话完整页读取和现有WebView显示的方案。0.7.3先接入有明确日志证据的本科系统,研究生流程保持原有实现。
|
||||
|
||||
## 实现边界
|
||||
|
||||
Android原生读取只允许准确学校域名下有限的只读路由、HTTPS默认端口及GET;拒绝凭证或业务操作查询字段、跳转、非HTML、超限响应。连接使用默认TLS校验,读取超时和解压前后均有上限。Cookie由原生CookieManager取出,仅发往原学校;返回Cookie限制为同域和系统路径。不写磁盘或日志。
|
||||
|
||||
完整HTML经Flutter确认公共脚本、CSS及已登录结构后,原生使用20秒有效的单次令牌恢复页面。页面URL、WebView实例、当前登录Cookie和Flutter文档代次均需匹配;恢复地址和来源保留原学校HTTPS。一个文档最多尝试一次、一次打开最多四次;暂存全局最多四项,后台读取两个工作线程和两个排队任务。失败保留当前页面,导入仍沿用原有确认与保存流程。
|
||||
@@ -0,0 +1,17 @@
|
||||
# TPSchedule 0.7.3 独立审查
|
||||
|
||||
2026-10-15,审查范围为本科完整页恢复、Android会话读取及临时令牌,不含原始学生附件或凭证。审查者仅获得需求、代码位置和验证范围,无本会话历史;未修改源码或运行重复构建。
|
||||
|
||||
## 发现与处理
|
||||
|
||||
P2:最初原生最终渲染仅比较WebView实例、URL及Cookie。相同URL、相同Cookie的新文档可能在Flutter最后一次检查和原生渲染之间替换旧文档,旧结果仍可通过检查;取消也未主动失效原生令牌。
|
||||
|
||||
已增加私有、不可枚举的每文档随机标记,随完整页读取传递;最终渲染先在真实WebView核对标记与URL,回调再检查临时令牌、视图实例、URL、Cookie及桥接生命周期,然后消费令牌并加载。页面开始、关闭、重置和销毁主动失效原生候选;异步渲染增加超时。回归覆盖原生校验等待中取消、相同URL新文档旧标记拒绝。实际脚本测试确认标记在同文档内稳定、跨文档变化,跳转和密码框跳过且不读取私密数据。
|
||||
|
||||
复审结论:在公开WebView能力与原生接受渲染作为提交点的边界内,该问题已处理,无其他阻塞项。跨进程页面导航与JS验证回调不具备形式上的绝对原子性;本实现不替换插件浏览器客户端,也不使用可能残留脚本全局状态的document.write替换方式。
|
||||
|
||||
## 验证与限制
|
||||
|
||||
原生16项JVM回归及API36实际渲染检查通过,实际URL、来源、中文、相对路径脚本/CSS、会话和文档保护均验证。Flutter完整套件265项通过,随后新增的取消渲染回归包含于8项恢复测试并通过,静态检查无问题。新增4个Node脚本中的恢复脚本及此前3个脚本均通过。最终交付详见tpschedule-0.7.3-validation.md。
|
||||
|
||||
学校真实账户、校园网络与用户手机Chromium156的联调仍由用户复测。离线和模拟器结果不代表线上组件已确认恢复。
|
||||
@@ -0,0 +1,33 @@
|
||||
# TPSchedule 0.7.3+21:本科教务完整页面恢复
|
||||
|
||||
2026-10-15,工程F:/program/app。按用户已确认的同会话完整页恢复设计实现;本版包含实际恢复逻辑。
|
||||
|
||||
## 证据和范围
|
||||
|
||||
更正后的0.7.2日志显示认证成功但jQuery不存在,页面只有两个脚本、没有样式或样式链接。Beangle旧框架会依据X-Requested-With头是否存在省略公共head,而Android WebView有自动添加该头的实现。源码与日志吻合,但尚未捕获该手机的实际线上请求,不能将推断写成已确认的网络事实。分析和官方源码链接见[证据与设计](school-webview-missing-head-analysis-2026-10-15.md)。
|
||||
|
||||
本版先对本科系统启用恢复,研究生流程不变。无需更换浏览器内核,学校账号和验证码继续由学生在学校网页填写。本科仍需自行打开课表和选择学期,再点击导入。
|
||||
|
||||
## 实现
|
||||
|
||||
识别已认证而公共依赖缺失的页面后,原生沿用Cookie与浏览器标识GET原学校HTTPS只读地址,不携带X-Requested-With。禁止自动跳转及表单提交,检查状态、类型、大小、超时和Cookie作用域。完整HTML通过结构校验后,在相同WebView恢复,并保留学校原URL和来源。20秒临时令牌、文档代次及同会话检查避免迟到结果覆盖新页面;失败、关闭或切换时保留旧页面和旧课表。重试和并发有上限。
|
||||
|
||||
新增school_full_page_restore固定状态日志,记录requested/applied/rejected/failed/cancelled及固定错误类别。原始HTML、正文、URL查询、Cookie和密码均不写日志;反馈协议和服务端部署不变。
|
||||
|
||||
## 验证记录
|
||||
|
||||
核心恢复及Android读取先观察到回归失败,再实现并通过。Flutter覆盖完整页恢复、片段/登录表单/外部base/重定向拒绝、切页取消、重复恢复保护,以及原生渲染开始回调存在或缺失的两种会话路径。
|
||||
|
||||
Android JVM检查覆盖省略头部的模拟框架、请求头与会话、GET和禁止跳转、路由限制、MIME、压缩大小、Cookie作用域及临时令牌生命周期。API36模拟器的实际WebView渲染验证了原URL与origin、中文、相对路径外部脚本与CSS,以及地址/会话变化时不替换DOM。模拟器Chromium133.0.6943.137,与用户156.0.8078.4不同。
|
||||
|
||||
完整Flutter套件265项通过,随后新增的渲染等待中取消回归在8项恢复测试中通过;静态检查无问题。4个Node脚本检查通过,原生JVM16项通过,Android原生渲染检查和Flutter原生浏览器测试各1项通过。独立审查提出的相同URL文档竞态已补上私有文档标记、原生失效和异步后复核,复审无阻塞项,见[审查记录](tpschedule-0.7.3-review.md)。上述测试不能代替校园网内真实学校账号复测。
|
||||
|
||||
## 用户复测
|
||||
|
||||
覆盖安装0.7.3,连接校园网后选择电子科技大学(本科生)并登录。缺少依赖时应出现“正在恢复完整教务页面”,随后确认学校菜单与组件能显示;打开课表选择学期后导入,再检查考试查询。若仍异常,立即导出本次新日志,检查恢复状态和固定失败类别。
|
||||
|
||||
## 安装包核对
|
||||
|
||||
发布包构建成功,com.tpschedule.app,versionName=0.7.3、versionCode=21,minSdk24、targetSdk36。TPSchedule-0.7.3.apk与TPSchedule.apk字节相同,60155727字节,SHA256为E78FD460F006EA879BC9BBCF24BCADB0377686E0A4DDDE2A00EBB218417F7E0E。
|
||||
|
||||
与0.7.2证书逐字节一致,证书SHA256为AF5C21B1BA1E48E461D8EA38DF0FE1C3653F64EB7E8E7728BAE6E5D988BA0D0A。源码包由最终提交生成,不含原始学生附件、私钥或运行缓存。登记冻结及旧版安装包在交付打包时重新校验。
|
||||
Reference in New Issue
Block a user