You need to enable JavaScript to run this app. 安卓端借助Jsoup登录SRM大学Academia站点失败的技术求助
优惠活动
大模型
产品
解决方案
定价
更多

安卓端借助Jsoup登录SRM大学Academia站点失败的技术求助

登录失败核心原因
  • 你当前的实现完全跳过了登录流程的前置步骤,直接向signin.ac接口发送POST请求,没有携带服务端预先下发的会话标识、表单校验令牌,这是请求被拒的核心原因。
  • 这类带OAuth交互的SSO登录站点,完整链路是「GET登录页→获取会话Cookie+页面内嵌的隐藏动态参数→携带上述凭证POST账号密码→手动跟随OAuth授权链路的多次重定向,逐步收集跳转过程中下发的会话Cookie→最终拿到主站的有效登录态」,绝非单步POST就能完成。
  • 手动传入JSESSIONID无效,是因为这个会话ID必须是服务端在你首次访问登录页时下发、和你的请求指纹、表单令牌绑定的有效上下文,随便填充的ID没有对应会话记录,会直接被服务端拦截。
  • 你代码里硬编码的client_portal、dcc、serviceurl等参数都是页面动态生成的临时值,硬编码很容易因为参数过期、值不匹配导致校验失败。
修正后的实现代码
  1. 第一步:先发起GET请求访问登录页,建立初始会话
    全程所有请求复用同一个Cookie集合,不要中途新建会话,同时自动解析登录页里的所有隐藏表单字段,不再硬编码参数值:
    // 全局维护统一的会话Cookie容器,全链路复用
    Map<String, String> sessionCookies = new HashMap<>();
    String fixedUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36";
    Map<String, String> loginParams = new HashMap<>();
    
    try {
        // 先GET登录页,拿初始Cookie
        Connection.Response loginPageResp = Jsoup.connect("https://academia.srmist.edu.in/accounts/signin.ac")
                .userAgent(fixedUA)
                .method(Connection.Method.GET)
                .execute();
        sessionCookies.putAll(loginPageResp.cookies());
    
        // 解析登录页所有隐藏表单字段
        Document loginPageDoc = loginPageResp.parse();
        for (Element hiddenInput : loginPageDoc.select("form input[type=hidden]")) {
            loginParams.put(hiddenInput.attr("name"), hiddenInput.attr("value"));
        }
        // 填入账号密码
        loginParams.put("username", 你的用户名);
        loginParams.put("password", 你的密码);
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  2. 第二步:携带初始会话和表单参数发POST登录请求,手动处理OAuth重定向链路
    关键是关闭自动重定向,逐步收集每一步跳转下发的Cookie,不跳过任何OAuth授权环节:
    try {
        Connection.Response postLoginResp = Jsoup.connect("https://academia.srmist.edu.in/accounts/signin.ac")
                .data(loginParams)
                .cookies(sessionCookies)
                .userAgent(fixedUA)
                // 关闭自动重定向,手动跟踪OAuth跳转
                .followRedirects(false)
                .method(Connection.Method.POST)
                .execute();
        sessionCookies.putAll(postLoginResp.cookies());
    
        // 手动跟完所有跳转
        String nextRedirect = postLoginResp.header("Location");
        while (nextRedirect != null) {
            // 补全相对路径
            if (nextRedirect.startsWith("/")) {
                nextRedirect = "https://academia.srmist.edu.in" + nextRedirect;
            }
            Connection.Response redirectStep = Jsoup.connect(nextRedirect)
                    .cookies(sessionCookies)
                    .userAgent(fixedUA)
                    .followRedirects(false)
                    .execute();
            sessionCookies.putAll(redirectStep.cookies());
            nextRedirect = redirectStep.header("Location");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    
  3. 第三步:用全链路收集的完整会话访问主站
    try {
        Document homePage = Jsoup.connect("https://academia.srmist.edu.in/")
                .cookies(sessionCookies)
                .userAgent(fixedUA)
                .get();
        Log.d("login", "已登录页面内容:" + homePage.text());
    } catch (IOException e) {
        e.printStackTrace();
    }
    
高频踩坑提醒
  • 全程User-Agent必须保持一致,中途更换请求指纹会导致服务端判定会话不匹配,直接返回未登录页面。
  • 不要每步请求都新建Cookie集合,也不要手动填充没有来源的JSESSIONID,所有Cookie都必须是服务端在请求链路中实际下发的,否则会话校验永远无法通过。
  • 一定要把followRedirects设为false手动跟踪跳转,Jsoup默认的自动重定向逻辑有时候会遗漏重定向过程中设置的Cookie,导致最后会话不完整,即便跳转到了主站也是未登录状态。
  • 不要硬编码表单参数值,登录页的动态参数必须从页面实际解析后携带,硬编码的固定值会随着服务端参数更新直接失效。
  • 如果请求被WAF拦截,可以补充和浏览器一致的Accept、Accept-Language请求头,降低被识别为爬虫的概率。

内容的提问来源于stack exchange,提问作者Shubham Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 19:45:03