實(shí)戰(zhàn):模擬登錄高校教務(wù)系統(tǒng)(帶驗(yàn)證碼)

高校登錄界面預(yù)覽

高校教務(wù)處登錄界面

模擬登錄分析

登錄請(qǐng)求的信息

說(shuō)明:
Request URL 登錄請(qǐng)求的地址(固定)
Request Method 登錄請(qǐng)求的方式(固定)
Location 登錄成功后跳轉(zhuǎn)的頁(yè)面(請(qǐng)求返回的結(jié)果)
Cookie 當(dāng)前會(huì)話信息(第一次訪問(wèn)登錄界面,會(huì)返回一個(gè)Cookie信息)
Form Data 需要Post的參數(shù)

  • __VIEWSTATE (固定)
    txtUserName (學(xué)號(hào))
    btnLogin.x (登錄按鈕點(diǎn)擊的位置)
    btnLogin.y (登錄按鈕點(diǎn)擊的位置)
    txtPassword (密碼)
    CheckCode (驗(yàn)證碼)
  • __EVENTVALIDATION (固定)

使用Spring Boot 開(kāi)發(fā)模擬登錄功能

效果圖

自己開(kāi)發(fā)的登錄界面
//模擬登陸的服務(wù)層
@Service
@Log4j
public class CtguService {
  //登錄請(qǐng)求地址
  private final static String LOGIN = "http://210.42.38.26:84/jwc_glxt/Login.aspx?__VIEWSTATE=%s&__EVENTVALIDATION=%s&txtUserName=%s&btnLogin.x=0&btnLogin.y=0&txtPassword=%s&CheckCode=%s";
  //登錄界面
  private final static String LOGIN_VIEW = "http://210.42.38.26:84/jwc_glxt/";
  //驗(yàn)證碼請(qǐng)求地址
  private final static String CHECK_CODE = "http://210.42.38.26:84/jwc_glxt/ValidateCode.aspx";
  //固定的參數(shù)值(URL編碼)
  private static final String VIEWSTATE = "%2FwEPDwUKMTQ4NjM5NDA3OWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFCGJ0bkxvZ2luU077LK9itKNe3fhI7aoZZ%2BS5Ryo%3D";
  private static final String EVENTVALIDATION = "%2FwEWBQKOmrqLAwKl1bKzCQKC3IeGDAK1qbSRCwLO44u1DVzfq830wXTY29pyqB1kTMdgWLfG";
  
  private Map<String, String> cookies;
  //驗(yàn)證碼
  private byte[] checkPic;
  
  //模擬訪問(wèn)登錄界面
  public void getCookiesFromJwc(){
    try {
      //第一次訪問(wèn)登錄界面
      Response response = Jsoup.connect(LOGIN_VIEW).timeout(60000).execute();
      //得到系統(tǒng)返回的Cookies
      cookies = response.cookies();
      //請(qǐng)求獲得驗(yàn)證碼的內(nèi)容
      checkPic = Jsoup.connect(CHECK_CODE).cookies(cookies).ignoreContentType(true).execute().bodyAsBytes();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  //登錄校驗(yàn)
  public boolean loginCheck(String username, String password, String checkCode){
    try {
      String loginUrl = String.format(LOGIN, VIEWSTATE, EVENTVALIDATION, username, password, checkCode);
      log.info("學(xué)號(hào):" + username + "  密碼:" + password);
      Document document = Jsoup.connect(loginUrl).cookies(cookies).timeout(60000).ignoreContentType(true).get();
      //登錄成功后,返回的Document有此節(jié)點(diǎn),作為是否登錄成功的依據(jù)
      Elements elements = document.select("span#ctl00_lblSignIn");
      if (!elements.isEmpty()){
        return true;
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return false;
  }

  public byte[] getCheckPic(){
    return checkPic;
  }
}
//模擬登錄視圖層
@Controller
public class HomeController {
  @Autowired
  private CtguService ctguService;

  //登錄界面
  @RequestMapping("login")
  public String login(Model model){
    ctguService.getCookiesFromJwc();
    return "login";
  }

  //驗(yàn)證碼顯示
  @RequestMapping("/ctgu/check")
  public void getPic(HttpServletResponse response) throws IOException {
    byte[] picBytes = ctguService.getCheckPic();
    response.setContentType("image/png");
    OutputStream stream = response.getOutputStream();
    stream.write(picBytes);
    stream.flush();
    stream.close();
  }
}
//html前端代碼
<p class="lead col-md-6 col-sm-12 col-md-offset-3">
    <input type="text" id="username" placeholder="學(xué)號(hào)" class="form-control">
</p>
<p class="lead col-md-6 col-sm-12 col-md-offset-3">
    <input type="text" id="password" placeholder="教務(wù)處密碼" class="form-control">
</p>
<p class="lead col-md-6 col-sm-10 col-md-offset-3">
    <input type="text" id="checkCode" placeholder="驗(yàn)證碼" class="form-control">
</p>
<p class="lead col-md-2 col-sm-2">
    <img th:src="@{/ctgu/check}" style="border-width:0px;">
</p>
<p class="lead col-md-6 col-sm-12 col-md-offset-3">
    <a href="#" class="btn btn-lg btn-success" id="signIn">注冊(cè)</a>
</p>

疑點(diǎn)

支持高并發(fā)的話,應(yīng)該要對(duì)Service層的Cookies 和 checkPic額外處理,這就留給讀者們?nèi)ニ伎剂?,并發(fā)量不大的話,這樣處理就沒(méi)什么問(wèn)題了

補(bǔ)充

  1. 個(gè)人原因,不能提供完整項(xiàng)目代碼,有問(wèn)題可以留言;
  2. 核心框架SpringBoot,依賴了Jsoup 和 Lombok;
  3. 中間有很多細(xì)節(jié),為什么要在拿到cookie后直接去獲取驗(yàn)證碼?不獲取會(huì)發(fā)生?有興趣的可以自行嘗試
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,661評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,231評(píng)論 25 708
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,821評(píng)論 11 349
  • 我站在麥田中央, 望向四野! 仲夏的風(fēng)吹起我的頭發(fā), 拂過(guò)我的眼睛。 熱辣辣的, 這就是夏的感覺(jué)! 麥的香味撲鼻而...
    衣飾憶流年閱讀 403評(píng)論 7 4
  • 清晨 我背起一籮筐注水的詩(shī) 去菜市場(chǎng) 不幸,歲月絆倒了我 晌午的太陽(yáng) 曬著白色的床單,特別暖和 努力著伸展雙臂,向...
    三尺冷閱讀 279評(píng)論 0 7

友情鏈接更多精彩內(nèi)容