東大校園網一鍵登錄


  東大校園網很不好用,我在宿舍連着網。當我出去自習的時候,也想用網,就連不上。
       因為東大校園網只允許一個人使用,這使得想合伙共用一個賬號的人就沒法整了。學校這么做多半是為了多掙點錢,這對於一個月只用2,3G的人是一種剝削。既然制度不對,為什么不改呢?
       於是只能先斷開一下,在重新登陸校園網了。可是坑爹的問題又出現了,有三個按鈕:連接,斷開連接,斷開全部連接。
        我點了“斷開網絡”,然后再“連接網絡”,它還告訴我:當前連接數大於一。
        實際上,只有一個管用:應該點“斷開全部連接”,再點“連接網絡”。
        那么就得分析一下為啥會有這種逗比的情況:編這個頁面的人多半是同情貧苦大眾的,他以為學校肯定會開明到允許多個學生共用一個賬號(然而他高估了學校),這樣一來,中間那個按鈕就起作用了,那個按鈕就是為多個用戶共用一個賬號而生的。但是最終那個按鈕沒能派上用場,反倒成了累贅,總是誤導人,不信可以統計一下,有多少人在一分鍾之內先點了“斷開連接”,然后又點了“斷開全部連接”,這就說明又多少次點中間按鈕是不管用的,是不符合人類需求的。學校既然狠心一人一個賬號來剝削群眾,為啥就不刪除哪一個按鈕呢?
        連上了網,一下子還開了一個小窗口,為啥不把這個窗口所顯示的信息跟頁面合並呢。這就使得我被迫多移動一次鼠標去關它。
        實際上,這個功能是后來添加的。http://jifei.neu.edu.cn/stats/dashboard?sid=12815848134566654這個鏈接里面的參數sid是隨機生成的,發送到服務器上,服務器完成查詢之后,將流量信息保存到一個hash表中,鍵是這個隨機數,值是流量使用情況。所以這個是實現是有可能出bug的,就是可能撞車,張三和李四同時登陸校園網,可能張三看到的流量信息是李四的。
如果用linux登陸校園網,可以用下面這個腳本,把用戶名和密碼改一下就可以了。
#!/bin/bash
#use 'ping' to check whether you are connected to NEU
ping -c2 'www.neu.edu.cn' || { echo "You should connect to NEU firstly" ;exit 0 ; }
user='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
password='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
temp=`mktemp`
#disconnect all the connections
curl -d "uid=$user&password=$password&range=2&timeout=1&operation=disconnectall" "http://ipgw.neu.edu.cn/ipgw/ipgw.ipgw" -o $temp 
iconv -f "gb2312" -t "utf-8"  $temp  -o $temp
cat $temp | grep '<td>.*</td>'
#if ask connect,connect it
if test $# -eq 0;then
    curl -d "uid=$user&password=$password&range=2&timeout=1&operation=connect" "http://ipgw.neu.edu.cn/ipgw/ipgw.ipgw" -o $temp
    iconv -f "gb2312" -t "utf-8"  $temp  -o $temp
    cat $temp | grep '<td>.*</td>'
fi
#output how much energy did you use .
curl -d "uid=$user&password=$password" "http://jifei.neu.edu.cn/stats/dashboard?sid=0" -o $temp 
curl "http://jifei.neu.edu.cn/stats/dashboard?sid=0" -o $temp  
res=`cat $temp | grep '<li>.*MB</li>'`
res=${res//[<li>,<\/li>]/}
echo "$res"


還可以用一個網頁打開,原理是用js向服務器post表單,自動登陸。
<html>
<script>
    var name='stu_20124003';
    var password="xxxxxxxxxxxxxxxxxxxxxxxxxxx";
    var user="uid="+name+"&password="+password;
    var data=user+"&range=2&timeout=1&";
    var x="http://ipgw.neu.edu.cn/ipgw/ipgw.ipgw";
    var y= "http://jifei.neu.edu.cn/stats/dashboard?sid=0";
    function post(url,data){
        var q=new XMLHttpRequest();
        q.open("post",url);
        q.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        q.send(data);
    } 
       post(x,encodeURI(data+"operation=disconnectall"));
       post(x,encodeURI(data+"operation=connect"));
       post(y,encodeURI(user));
    location=y;
</script>
</ht

===============java版==================

import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;

public class URLConnectionPost {
 static void post(String url, String data) {
  try {
   URLConnection connection = new URL(url).openConnection();
   connection.setDoOutput(true);
   connection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
   OutputStream cout = connection.getOutputStream();
   cout.write(data.getBytes());
   cout.close();
   connection.getInputStream();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public static void main(String[] args) {
  String name = "stu_20124003", password = "xxxxxxxxxxxxx";
  String user = "uid=" + name + "&password=" + password, data = user + "&range=2&timeout=1&";
  String x = "http://ipgw.neu.edu.cn/ipgw/ipgw.ipgw", y = "http://jifei.neu.edu.cn/stats/dashboard?sid=0";
  post(x, data + "operation=disconnectall");
  post(x, data + "operation=connect");
  post(y, user);
  try {
   Scanner cin = new Scanner(new URL(y).openConnection().getInputStream());
   while(cin.hasNext()){
    System.out.println(cin.nextLine());
   }
   cin.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}


在連接校園網之前程序會點擊“斷開全部連接”,然后再點擊“連接”。所以只要連着校園網,一旦打開這個網頁就肯定登陸了。
======================
4.20日更新
現在,東大校園網改版了,確實是變好了不少。首先,那個顯示流量的彈框沒了,變成了ajax請求;其次,手機端變得漂亮多了.
java大法好
public class Main { static String tos(InputStream cin) { Scanner in = new Scanner(cin); String ans = ""; while (in.hasNext()) { ans += in.nextLine() + "\n"; } in.close(); return ans; } static InputStream post(String url, String data) { try { URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); connection.setRequestProperty("content-type", "application/x-www-form-urlencoded"); OutputStream cout = connection.getOutputStream(); cout.write(data.getBytes()); cout.close(); return connection.getInputStream(); } catch (Exception e) { System.out.println("沒連校園網"); // e.printStackTrace();
 } return null; } public static void main(String[] args) { String name = "stu_20124003", password = "xxxxxxxxx"; String user = "username=" + name + "&password=" + password; String base = "http://ipgw.neu.edu.cn:803/"; String logout = base + "include/auth_action.php"; String login = base + "srun_portal_pc.php?ac_id=1&"; post(logout, user + "&action=logout&ajax=1"); post(login, user + "&action=login&ac_id=1"); InputStream cin = post(logout, "action=get_online_info"); String s[] = tos(cin).split(","); System.out.println("已用流量:"
                + new DecimalFormat("#,###").format(Long.parseLong(s[0]))); long time = Long.parseLong(s[1]); System.out.println("登錄時間:" + String.format("%02d:%02d:%02d", time / 3600, (time / 60) % 60, time % 60)); System.out.println("賬戶余額:" + s[2]); System.out.println("IP地址:" + s[5]); } }

 順道學學python

from urllib.request import Request, urlopen def post(url, data, doCallback): req = Request(url) fd = urlopen(req, data.encode(encoding='utf_8')) if(doCallback): return fd.read().decode("utf_8") name = "stu_20124003" password = "xxxxxxxx" user = "username=" + name + "&password=" + password base = "http://ipgw.neu.edu.cn:803/"; logout = base + "include/auth_action.php"; login = base + "srun_portal_pc.php?ac_id=1&"; post(logout, user + "&action=logout&ajax=1", False) post(login, user + "&action=login&ac_id=1", False); ans = post(logout, "action=get_online_info", True) value = ans.split(sep=',') def formatFlux(s): ans = "" danwei = "B,K,M,G".split(",") i=len(danwei)-1
    while i>=0: if i*3<=len(s): ans+=s[max(len(s)-i*3-3,0):len(s)-i*3]+danwei[i]+' ' i=i-1
    return ans print("已用流量:" + formatFlux(value[0])) t = int(value[1]) print("登錄時間:%02d:%02d:%02d" % (t / 3600, (t / 60) % 60, t % 60)) print ("賬戶余額:" + value[2]) print("IP地址:" + value[5])

 javascript也好用,不過是setHeader幾下罷了。

<html>
<h1 id='haha'></h1>
<script>
    var name = 'stu_20124003'; var password = "xxxxxxxxx"; var user = "username=" + name + "&password=" + password; function post(url, data, doCallback) { var q = new XMLHttpRequest(); q.open("post", url); q.setRequestHeader('Referer', 'http://ipgw.neu.edu.cn:803'); q.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 q.setRequestHeader("Origin","http://ipgw.neu.edu.cn:804");
if (doCallback) { q.onreadystatechange = function(q) { if (q.readyState == 4 && q.status == 200) { document.getElementById('haha').innerHtml = q.responseText; } }; } q.send(data); } var base = "http://ipgw.neu.edu.cn:803/"; var logout = base + "include/auth_action.php"; var login = base + "srun_portal_pc.php?ac_id=1&"; post(logout, user + "&action=logout&ajax=1", false); post(login, user + "&action=login&ac_id=1", false); post(logout, "action=get_online_info", true); </script> </html>

 林教主發現,斷開連接時還需要post用戶名,無需post正確的密碼,后台沒有對密碼進行檢測是否正確.於是,林教主把全校人的校園網斷開了一遍.

現在我來北航了,北航校園網1G只要5毛錢,允許多人同時在線,節假日免費,每月初贈送1G,登錄頁面還算漂亮.總而言之,北航校園網比東北大學建設的好多了.

public class Main {
    static boolean post(String url, String data) throws IOException {
        URLConnection connection = new URL(url).openConnection();
        connection.setDoOutput(true);
        OutputStream cout = connection.getOutputStream();
        cout.write(data.getBytes());
        cout.close();
        StringBuilder builder = new StringBuilder();
        Scanner cin = new Scanner(connection.getInputStream());
        while (cin.hasNext()) {
            builder.append(cin.nextLine());
        }
        cin.close();
        return builder.toString().contains("login_ok");
    }
    public static void main(String[] args) throws IOException {
        String username = "xxxxx", password = "xxxxx";
        while (false == post(
                "https://gw.buaa.edu.cn:802/include/auth_action.php",
                "action=login&username=" + username + "&password={B}"
                        + Base64.getEncoder()
                                .encodeToString(password.getBytes())
                        + "&save_me=1&ajax=1&ac_id=4"));
    }
}

用python的requests庫實現起來更簡單

import requests
import base64

username = "xxxx"
password = "xxxx"

def go(action="login"):
    resp = requests.post("https://gw.buaa.edu.cn:802/include/auth_action.php", data={
        "action": action,
        "username": username,
        "password": "{B}" + base64.encodebytes(password.encode("utf8")).decode("utf8"),
        "save_me": 0,
        "ajax": 1,
        "ac_id": 22,
    })
    resp.encoding = "utf8"
    print(resp.text)

go("login")

手機端登錄時,需要打開瀏覽器輸入用戶名密碼,十分麻煩,所以編了一個android app,方便一鍵登錄.本程序能自動打開wifi,鏈接校園網,然后點一下登錄並退出就可以了.把用戶名和密碼存儲在SharedPreference里面,因為android經驗很少,特此記錄.

Main.java:本程序唯一的Activity

public class Main extends Activity implements View.OnClickListener {
    Button loginButton, exitButton;
    EditText username, password;
    TextView info;
    Handler handler = new Handler();
    SharedPreferences sharedPreferences;
    Semaphore semaphore = new Semaphore(1);
    Runnable runnable = new Runnable() {
        long lastLoginTime = 0;

        @Override
        public void run() {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (System.currentTimeMillis() - lastLoginTime < 3000) {
                return;
            } else {
                lastLoginTime = System.currentTimeMillis();
                login(username.getText().toString(), password.getText().toString());
            }
            semaphore.release();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        loginButton = (Button) findViewById(R.id.login);
        exitButton = (Button) findViewById(R.id.exit);
        username = (EditText) findViewById(R.id.username);
        password = (EditText) findViewById(R.id.password);
        info = (TextView) findViewById(R.id.info);
        loginButton.setOnClickListener(this);
        exitButton.setOnClickListener(this);
        init();
        username.setText(sharedPreferences.getString("username", ""));
        password.setText(sharedPreferences.getString("password", ""));
    }

    void init() {
        WifiManager wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
        wifiManager.setWifiEnabled(true);
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"BUAA-WiFi\"";
        int netId = wifiManager.addNetwork(config);
        wifiManager.enableNetwork(netId, true);
        sharedPreferences = this.getSharedPreferences("wifi", 0);
    }

    @Override
    public void onClick(View v) {
        if (v == exitButton) {
            finish();
            System.exit(0);
        }
        if (username.getText().length() == 0 || password.getText().length() == 0) {
            Toast.makeText(this, "please input username&password", Toast.LENGTH_LONG).show();
            return;
        }
        if (semaphore.availablePermits() == 1) {
            new Thread(runnable).start();
        }
    }

    boolean post(String url, String data) throws IOException {
        URLConnection connection = new URL(url).openConnection();
        connection.setDoOutput(true);
        OutputStream cout = connection.getOutputStream();
        cout.write(data.getBytes());
        cout.close();
        StringBuilder builder = new StringBuilder();
        Scanner cin = new Scanner(connection.getInputStream());
        while (cin.hasNext()) {
            builder.append(cin.nextLine());
        }
        cin.close();
        return builder.toString().contains("login_ok");
    }

    void login(String username, String password) {
        try {
            int cnt = 2;
            while (cnt-- > 0 && !post(
                    "https://gw.buaa.edu.cn:802/include/auth_action.php",
                    "action=login&username=" + username + "&password={B}"
                            + Base64.encodeToString(password.getBytes(), Base64.DEFAULT)
                            + "&save_me=1&ajax=1&ac_id=4"))
                Thread.sleep(1000);
            if (cnt > 0) {
                sharedPreferences.edit().putString("username", Main.this.username.getText().toString()).putString("password", Main.this.password.getText().toString()).commit();
                exitButton.callOnClick();
            } else {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(Main.this, "login failed", Toast.LENGTH_LONG).show();
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

本程序布局文件:唯一的layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="username" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="password"
        android:inputType="textPassword" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/exit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="exit" />

        <Button
            android:id="@+id/login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="login&amp;exit" />

    </LinearLayout>

    <TextView
        android:id="@+id/info"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

 用網絡請求的方式登錄校園網有時無法成功,這是可以模擬瀏覽器,這樣登錄成功率百分之百,但是運行速度有些慢.下面代碼用到HtmlUnit庫.創建maven項目並添加HtmlUnit的依賴即可.

public class App {
    public static void main(String[] args) throws Exception {
        WebClient client = new WebClient(BrowserVersion.CHROME);
        HtmlPage page = client.getPage(
                "https://gw.buaa.edu.cn:802/beihanglogin.php?ac_id=22&url=http://gw.buaa.edu.cn:802/beihangview.php");
        HtmlTextInput loginname = (HtmlTextInput) page.getElementById("loginname");
        HtmlPasswordInput password = (HtmlPasswordInput) page.getElementById("password");
        HtmlSubmitInput button = (HtmlSubmitInput) page.getElementById("button");
        loginname.setValueAttribute("xxxxx");
        password.setValueAttribute("xxxxx");
        button.click();  
        client.close();
    }
}

 

帶配置文件的登錄,第一次登錄時會提示輸入用戶名密碼並保存到家目錄下。

import base64

import requests
import warnings
import time
import os
import json
warnings.filterwarnings("ignore")


def login(username, password):
    print(username,password)
    resp = requests.post("https://gw.buaa.edu.cn:803/include/auth_action.php",
                         data={
                             "action": "login",
                             "username": username.lower(),
                             "password": "{B}" + base64.encodebytes(password.encode("utf8")).decode("utf8"),
                             "save_me": 0,
                             "ajax": 1,
                             "ac_id": 22
                         }, verify=0)
    resp.encoding = "utf8" 
    if "login_ok" in resp.text:
        return True
    else:
        return False


filename = os.path.join(os.path.expanduser("~"), '.school-net.json')
if os.path.exists(filename):
    config = json.load(open(filename,encoding='utf8'))
    resp = login(config['username'], config['password'])
else:
    while True:
        username = input("please input username : ").strip()
        if not username:
            continue
        password = input("please input password : ").strip()
        if not password:
            continue 
        if login(username, password):
            break
        else:
            print("登錄失敗,可能是用戶名密碼錯誤")
    config = dict(username=username, password=password)
    json.dump(config, open(filename,mode="w"))
    resp = True

if resp:
    print("login ok")
else:
    print("login failed")
time.sleep(2)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM