d1y

博客园 首页 新随笔 联系 订阅 管理

最近用上了学校的校园网, 速度还行吧

不过校园网每次要 web登录认证, 就有点无语, 像我这么懒的人怎么可能每次都要重新登录一次

围观地址: https://github.com/jsxxzy/inet

原理很简单, 无非就是登录一个 POST 请求, 然后亿点点细节就可以了

懒才是第一生产力啊..

原理分析 2020-11-29

最近真的闲的不行, 没什么事情做, 奇怪的是室友不知道发生什么事了, 全都在学JAVA, 搞得我一脸懵逼(按理说不应该天天游戏吗/雾)

所以就写了一个java版本的校园网客户端: https://github.com/jsxxzy/inetl

首先查看入口函数: /src/main/java/io/xxzy/App.java

      System.out.println(" login: 登录");
      System.out.println("   get: 获取保存的账号密码");
      System.out.println("  save: 保存账号密码");
      System.out.println("   fix: 初始化账号密码");
      System.out.println(" check: 查询是否登录");
      System.out.println("  info: 查询信息");
      System.out.println("logout: 注销");
      System.out.println("=============>");

登录

校园网有登录的网端

稍微看一下就知道这就是简单的 post 请求

密码是经过 md5 机密, 加几个偏移值, 这几个偏移值在 html 片段里都有

/**
   * 生成密码
   * https://github.com/jsxxzy/ipsd
   * @return 密码
   */
  public String CreatePassword(String p) {
    String offset1 = constvar.Pid + p + constvar.Calg;
    String md5 = utilsx.CreateMD5(offset1);
    return md5 + constvar.Calg + constvar.Pid;
  }

请求之后, 后台返回的html片段, 比较恶心的是, 居然不是utf-8, 所以还需要将其转为utf-8格式

/**
   * 转为 `utf-8`
   */
  static String toUTF8(String input) {
    return new String(input.getBytes(), StandardCharsets.UTF_8);
  }

返回的html里有你需要的一些信息, 用来判断是否登录成功, 我们需要运行这段js然后通过判断变量msga来判断

但是第一步是去除其 <!--

/**
   * 运营商的js写的不标准, 此函数试图去除一些不标准
   *
   * 一开口就老外包了...
   *
   * @param raw 源数据
   * @return 正确的`js-code`
   */
  public static String jsCodeRemoveCommit(String raw) {
    String cp = raw.trim();
    String left = "<!--";
    String right = "// -->";
    if (cp.startsWith(left)) {
      cp = cp.substring(left.length());
    };
    if (cp.endsWith(right)) {
      int endIndex = cp.length() - right.length();
      cp = cp.substring(0, endIndex);
    }
    return cp;
  }

判断条件为, 若为空表示登录成功, 若为 5 多台设备在线, 若为 1 表示账号或密码错误

查询是否登录

查询是否登录只是查询信息alias

   // 未登录将会自动跳转到 `/0.htm` 登录界面, 但判断条件为 `title` 字符串为空
   String title = $.title();

查询信息

查询信息相对有点复杂, 访问校园路由, 然后和登录差不多, 先转utf-8然后拿到js, 运行, 就可以拿到了

// 运行`js`
void InitData(Document $) {
    js jsRuntime = new js();
    Elements jsData = $.select(constvar.QueryInfoSelectText);
    String jsDataText = jsData.get(0).html();
    String jsInputData = utilsx.jsCodeRemoveCommit(jsDataText);
    jsRuntime.RunScript(jsInputData);
    String cacheTimeString = jsRuntime.GetString(constvar.InfoTime);
    try {
      this.Time = Integer.parseInt(cacheTimeString);
    } catch (NumberFormatException e) {
      e.printStackTrace();
    }
    this.Ipv6 = jsRuntime.GetString(constvar.InfoIpv6);
    this.Ipv4 = jsRuntime.GetString(constvar.InfoIpv4);
    this.UID = jsRuntime.GetString(constvar.InfoUID);
    this.Xip = jsRuntime.GetString(constvar.InfoXip);
    this.Portalname = jsRuntime.GetString(constvar.InfoPortalname);
    String cacheFlowData = jsRuntime.GetString(constvar.InfoFlow);
    try {
      this.Flow = Integer.parseInt(cacheFlowData);
    } catch (NumberFormatException e) {
    }

注销

注销比较简单, 只是GET请求一下注销的路由即可

get | save | fix

存储账号到本地, 比较简单, 读写一个文件, 不过我自己实现了一个解析格式

/**
   * 解析格式
   */
  private String[] parseLocalAuth(String rawString) {
    String[] em = new String[0];
    if (rawString.length() == 0) {
      return em;
    }
    String[] arr = rawString.split(this.offset);
    if (arr.length <= 1) {
      return em;
    }
    String[] r = new String[2];
    r[0] = arr[0];
    r[1] = arr[1];
    return r;
  }

作者有话说

额, 迫于无聊编写的, 以前一直对于java有偏见, 但是写了以后发现好像还挺好的哈

posted on 2020-10-30 00:07  d1y  阅读(880)  评论(0编辑  收藏  举报