原文地址:https://www.jianshu.com/p/4d4f7e9b45b6

一、原理

  • 在超级课程表等APP中,大都有使用学号密码登录教务系统读取课程的功能。在这里我将模仿此功能使用J2V8、Jsoup等第三方库实现模拟登录教务系统读取信息。
  • 这里的教务系统以南昌大学教务系统(湖南强智科技教务系统)为例。

现在的大多数网站架构都是后台使用Session来进行用户验证,并向前端返回Cookie,前端的每次请求都带上这个Cookie以作为用户登陆态的保持与身份的认证。
另有部分网站(尤其是APP)使用JWT(JSON Web Tokens)进行登陆态验证,确认登录后前端请求带上返回的Token,也是大同小异。这里主要以前者为例。


我们先来梳理一下登录的流程

1. 前端向后台Servlet发送请求,返回验证码图片。请求头中携带Cookie。

向后台请求验证码图片

2.登录时,请求头中携带相应Cookie,并将账号密码编码后连同验证码一同post到后台

登录

3.若后台验证账号密码与验证码正确,则该Cookie已经作为本用户登录态的凭证,每次请求携带该Cookie即可访问相应权限的Url。

二、具体实现

  • 在Android代码中,我将所有Activity均继承于BaseActivity,BaseActivity中实现沉浸式标题栏的相应代码,将配置文件中的主题修改为@style/Theme.AppCompat.Light.NoActionBar以完成沉浸式标题栏。
/*** 封装可复用的代码,作为所有Activity的父类*/
public abstract class BaseActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);//region 沉浸式状态栏代码// 5.0以上系统状态栏透明if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = getWindow();window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(Color.TRANSPARENT);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}//endregionsetContentView(getViewId());}/***添加抽象方法,供子类绑定视图* @return*/abstract int getViewId();
}
  • 继续进行功能分析,首先,我们要向相应的Servlet发送请求,将验证码显示在App上。
  • 在这里我们使用的是jsoup: Java HTML Parser进行网络链接以及Cookie获取。

我们可以直接在jsoup官网下载对应jar包。为方便起见,我们在Maven Repository中找到jsoup的gradle依赖,并将其添加到build.gradledependencies中。

compile group: 'org.jsoup', name: 'jsoup', version: '1.11.2'

然后我们使用jsoup进行验证码的请求,并将Cookie信息保存下来。
(注:jsoup对网络的请求写在子线程中,通过handle对前端进行操作)

private String url_safecode = "http://jwc101.ncu.edu.cn/jsxsd/verifycode.servlet"; // 验证码
private Map<String, String> cookie;
class PicThread extends Thread{@Overridepublic void run() {Connection.Response response = null;try {response = Jsoup.connect(url_safecode).ignoreContentType(true) // 获取图片需设置忽略内容类型.userAgent("Mozilla").method(Connection.Method.GET).timeout(3000).execute();cookie = response.cookies();  //将cookie保存下来byte[] bytes = response.bodyAsBytes();//验证码保存为BitmapBitmap bitmap= BitmapFactory.decodeByteArray(bytes,0,bytes.length); Message message=new Message();message.what=0x123;message.obj=bitmap;handler.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}

Handle接受到Message后将验证码显示在界面的ImageView上。

handler=new Handler(){@Overridepublic void handleMessage(Message msg) {if(msg.what==0x123){imageView.setImageBitmap((Bitmap)msg.obj);}}};

OK,我们现在将验证码显示了出来并保存了Cookie,接下来就是将账号与密码Post到后台。这里要注意一个问题,我们通过之前的截图可以看到,登录时Post的账号与密码都是重新编码过的。
我们通过右键查看网页源代码可以看到,该编码过程账号和密码分别是调用conwork.js中的encodeInp方法,然后将编码后的密文用%%%进行连接。

编码

  • 这里有两种解决方案,一种解决方案是将加密算法使用Java重写一遍,这种方法比较麻烦,我在这里采用的是第二种方法,直接在Android中使用J2V8框架运行JS代码进行加密。

J2V8框架的添加方式与jsoup大同小异,在maven repository中找到J2V8的gradle依赖,然后添加到build.gradle中。

compile 'com.eclipsesource.j2v8:j2v8:4.5.0@aar'

将conwork.js放到项目目录的assets中,然后使用J2V8调用。

try {InputStream is=getAssets().open("conwork.js");   //获取用户名与密码加密的js代码BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder sb = new StringBuilder();String line = null;try {while ((line = reader.readLine()) != null) {sb.append(line);}V8 runtime = V8.createV8Runtime();      //使用J2V8运行js代码并将编码结果返回final String encodename = runtime.executeStringScript(sb.toString()+ "encodeInp('"+userin.getText().toString()+"');\n");final String encodepwd=runtime.executeStringScript(sb.toString()+"encodeInp('"+pwdin.getText().toString()+"');\n");runtime.release();} catch (IOException e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}}
} catch (IOException e) {e.printStackTrace();
}

然后我们将encodenameencodepwd使用jsoup来post到教务系统登录的url,post时带上之前保存的cookie。

(new Thread(){@Overridepublic void run() {Map<String, String> data = new HashMap<String, String>();   //进行Post的参数data.put("encoded", encodename+"%%%"+encodepwd);data.put("RANDOMCODE", verin.getText().toString());Connection connect = Jsoup.connect(url_Login).header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8").userAgent("Mozilla").method(Connection.Method.POST).data(data).timeout(3000);for (Map.Entry<String, String> entry : cookie.entrySet()) { //使用获取验证码时生成的cookieconnect.cookie(entry.getKey(), entry.getValue());}Connection.Response response = null;try {response = connect.execute();Pattern p=Pattern.compile("<title>(.*)</title>");Matcher m =p .matcher(response.body()) ;if( m. find()) {//通过response的title是否为"学生个人中心"来进行判断是否登录成功if((m.group(1).toString()).equals("学生个人中心")){//登录成功的相应代码}else{}}} catch (IOException e) {e.printStackTrace();}}
}).start();

这时我们就已经完成了模拟登录,之后可以使用这个cookie访问管理系统的各个url了。

三、最终效果

效果

  • Github地址:https://github.com/leosa/simulate-logon/tree/master

Android模拟登录教务系统(强智系统)相关推荐

  1. 【Android+OkHttp3+Jsoup】 模拟登录教务系统 抓取课表和成绩

    原文链接:https://blog.csdn.net/u013347241/article/details/52711018 今天这篇文章为大家带来的是模拟登录教务系统并抓取课表和成绩的详细实现过程. ...

  2. python计算学分绩点的程序_模拟登录教务系统计算GPA的小程序

    做了一些小游戏之后开始慢慢体会敲代码是件体力活,慢慢熬总能熬出来的.这几天又心血来潮想写个程序模拟登录教务系统计算GPA的小程序.不过之前没有一点点网络编程的经验,就趁着期中考后放假4天,一点点把坑填 ...

  3. Android模拟登录教务处(带验证码)

    前言:我们学习过Android之后,总想写出一两个属于自己的应用,作为学生,可能我们最想尝试的就是实现一个Android版教务处,可以查成绩,学分,绩点,课表,还有学校新闻这样的app吧.下面我们开始 ...

  4. python模拟登录教务系统_用Python实现模拟登录正方教务系统抢课

    最近学校开始选课,但是如果选课时间与自己的事情冲突,这时候就可以使用Python脚本自助抢课,抢课的第一步即是模拟登录,需要模拟登录后保存登录信息然后再进行操作. 而且整个流程是比较简单,这是因为正方 ...

  5. python输入学号查成绩_Python实践学习笔记:模拟登录教务系统实现微信查成绩

    python+selenium+itchat模拟登录学校教务系统,获取个人成绩,通过微信发送. 先看看最终效果: 〇.背景 学习python一段时间,觊觎学校的教务系统很久了. 寒假开始,大部分同学陆 ...

  6. android模拟登陆,Android模拟登录V2EX

    最近在撸一个V2EX的客户端,官方API缺少一些功能如登录,发帖等,撸完官方API总觉得少了什么,本篇文章主要通过模拟登录实现一些官方没提供API的功能 观察登录传输的数据 在网页上登录帐号,通过ch ...

  7. vue element之简约强智系统

    效果图: 代码找我博客下载.

  8. python实现强智科技教务系统抢课(两种方法)

    前言 又到了选课的时间,又一次被教务系统的预选给安排了,硬是一门都没选中.于是想实现有没有自动捡课的方法.就整体分为两种方法,一种是获取get请求然后由python多线程提交去选课,一种是利用自动化测 ...

  9. JSoup模拟登录新版正方教务系统(内网-教务系统)获取信息过程详解

    新版正方教务系统登录界面: 目录 一.需求分析 二.模拟登录内网 三.模拟登录教务系统 四.爬取成绩和课表信息 参考文章 一.需求分析   需要访问教务系统,爬取出课表成绩等信息,并在自己所写的APP ...

  10. java模拟登录新版正方_java 模拟登陆正方教务系统

    比较懒,主要说一下思路.. 1.首先正方教务系统的验证码当你不去向服务器申请的时候,可以直接无视它不需要去输入验证码.可以通过浏览器屏蔽学校教务系统的图片就可以直接输入账号密码回车进去.. 2.通过抓 ...

最新文章

  1. c++概念模型的官方解释
  2. ASM 磁盘、目录的管理
  3. 图像处理:镜头频率(衍射极限) 和 相机采样:显微镜的采样定理
  4. http://blog.csdn.net/churximi/article/details/61210129
  5. 程序员修神之路--kubernetes是微服务发展的必然产物
  6. 网关 Spring Cloud Gateway
  7. 【渝粤教育】国家开放大学2018年春季 0089-21TInternet和Intranet应用 参考试题
  8. 数据产品-数据可视化大作“数据大屏”
  9. 内部类、抽象类、接口基本知识详解
  10. 2015英特尔® 实感™ (Intel® RealSense™) 动手开发实验课
  11. python canny算法_Python 实现 Canny 边缘检测算法
  12. 32位单精度浮点数表示法
  13. GDB 使用教程(二)
  14. 小学生都能听懂的傅里叶变换讲解
  15. 使用Java实现简单串口通信
  16. java语言打印上三角和下三角,进一步得到九九乘法表
  17. linux openfire mysql_Linux系统安装openfire及其如何后台运行openfire
  18. unity 游戏版本更新插件
  19. 仿邓杰网站(港中旅)网站心得
  20. 一次安装IE11浏览器的经历

热门文章

  1. 【深度学习之美】全面连接困何处,卷积网络见解深(入门系列之九)
  2. 上市公司环境信息披露合集-上市公司环保补助金额、环保税等三大维度指标(2003-2020年)
  3. echarts 多个 geo 实现缩放拖拽同步
  4. MySQL InnoDB 存储引擎写入磁盘(落盘)的原理\MySQL怎么保证持久性、原子性?(MySQL中是如何实现事务提交和回滚的)\隔离性
  5. python setup.py build develop_python setup.py build develop编译出错
  6. windows桌面待办事项_提醒待办事项app哪个好用?苹果手机上有什么好用的提醒便签软件吗...
  7. MPB:使用QIIME 2分析微生物组16S rRNA基因扩增子测序数据(视频)
  8. 案例:通过空气质量指数AQI学习统计分析并进行预测(上)
  9. STM32芯片数据手册下载——官网免费下载方法
  10. c++学习笔记 第四部分