本文主要是想和你們探討技術,讓你們學會Cookie的使用,切勿作違法之事!
java
不少Android初學者在剛開始學習的時候,或多或少都想本身搞個應用出來,把本身學的十八般武藝全都用在這個APP上,其實這個想法很好,項目驅動學習,效率更高,這是大學老師教給個人。但是一個APP,若是純粹搞成一個本地應用,會變得很沒有意思,因此咱們通常仍是作網絡應用,網絡應用涉及到網絡服務器的搭建,數據的採集等等太過於耗時,有的人可能剛剛搭建一個網絡服務器就耗費了很長時間,搞得都沒有信心學習Android了,針對這種狀況,我通常建議你們本身去抓包。抓包又會遇到新問題,就是有可能你須要模擬登錄。所以,本文以知乎登錄爲例,帶你們來看看模擬登錄,同時也來看看OKHttp中Cookie的使用問題。web
爲何選擇知乎做爲切入點呢?沒什麼,在想到這個話題的一瞬間恰好想到了知乎!數據庫
實際上模擬登錄仍是很簡單的,麻煩的是須要咱們去仔細分析請求的接口和參數!瀏覽器
本文內容主要包括如下三個方面
緩存
1.知乎登錄接口和參數分析服務器
2.模擬登錄cookie
3.Cookie持久化網絡
OK,那就開始吧!
框架
本文采用Chrome瀏覽器來進行分析,首先打開知乎登陸頁面,以下:ide
按下F12,打開Chrome的調試窗口:
而後在知乎的登陸頁面輸入用戶名和登陸密碼,注意觀察調試窗口的日誌:
在這裏咱們能夠看到傳遞給服務器的參數主要有以下四個,分別是_xsrf,password,remember_me,以及email四個,remember_me很好理解,是否記住密碼,email實際就是咱們的帳號名稱,password實際就是咱們的登陸密碼,至於_xsrf則是登陸頁面的一個隱藏域,這個數據很容易拿到,同時,從這裏咱們還能夠看出知乎登陸時請求的接口是https://www.zhihu.com/login/email。
OK,分析完這些以後,咱們就能夠動手開始編碼了。
知道了知乎在登陸的過程當中須要傳遞哪些參數以後,接下來咱們就能夠動手模擬登陸。
用戶名、密碼以及記住我這三個參數很是容易記憶,很容易獲取,以後第一個參數稍微有些麻煩,咱們打開用戶登陸頁面的源碼,會看到以下一行代碼:
這個呢其實就是隱藏域的值。好了,如今登陸所須要的四個參數都知道從哪裏獲取了,那咱們就開始登陸吧,個人登陸頁面以下:
輸入用戶名和密碼,點擊登陸按鈕就能夠執行登陸操做了,可是在執行登陸操做以前,我須要先訪問知乎的登陸頁面,拿到那個隱藏域的值。因而乎,個人登陸邏輯是這樣:
先來看如何獲取隱藏域,這裏涉及到如何解析HTML文本,我在這裏用到了Jsoup庫,對該庫不瞭解的小夥伴請自行Google,核心代碼以下(完整代碼小夥伴們自行在文末下載該Project):
Request request = new Request.Builder().url("https://www.zhihu.com/#signin").build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String resp = response.body().string(); Document parse = Jsoup.parse(resp); Elements select = parse.select("input[type=hidden]"); Element element = select.get(0); String xsrf = element.attr("value"); Message msg = mHandler.obtainMessage(); msg.what = 1; msg.obj = xsrf; Log.d("google_lenve_fb", "onResponse: xsrf:" + xsrf); mHandler.sendMessage(msg); } });
FormBody formBody = new FormBody.Builder() .add("captcha_type", "cn") .add("_xsrf", xsrf) .add("password", passwordEt.getText().toString()) .add("remember_me", "true") .add("email", usernameEt.getText().toString()) .build(); Request request = new Request.Builder().post(formBody).url(loginUrl).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.d("google_lenve_fb", "onResponse: " + response.body().string().toString()); } });
{ "r":0, "msg":"登陸成功" }
但是單純的模擬登陸並無什麼意義,舉個栗子,咱們知道要想獲取用戶的私信,必須是登陸狀態才能獲取,在知乎中獲取用戶私信的頁面地址是:
https://www.zhihu.com/inbox
Cookie這個東西最先由網景的員工在1994年提出,他在他的原始說明文檔中解釋了Cookie工做原理的基本信息,該文本後來被做爲規範歸入到RFC 2965中,網景瀏覽器從一開始就支持Cookie,現現在全部的Web瀏覽器都支持Cookie。那麼Cookie究竟是什麼?其實就是瀏覽器存儲在用戶電腦上的一小段文本,該文本從何而來?在用戶首次登陸的時候,服務器會返回一段Cooike文本,瀏覽器將該文本存入到用戶的電腦中,之後每當用戶向該服務器發起網絡請求時,瀏覽器都會攜帶上這段文本,這樣服務器就知道該用戶是否已經登陸過了。
OK,上文是咱們對Cookie一個簡單的介紹,接下來咱們就來看看在咱們的OkHttp中如何實現Cookie的緩存。
OkHttp框架從3.0開始簡化了Cookie的使用,它提供了一個叫作cookieJar的API,只須要咱們實現該API中的方法便可,一個簡單的使用方式以下:
builder = new OkHttpClient.Builder(); builder.cookieJar(new CookieJar() { private final HashMap<String, List<Cookie>> cookieStore = new HashMap<String, List<Cookie>>(); @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { cookieStore.put(url.host(), cookies); } @Override public List<Cookie> loadForRequest(HttpUrl url) { List<Cookie> cookies = cookieStore.get(url.host()); return cookies != null ? cookies : new ArrayList<Cookie>(); } }); okHttpClient = builder.build();
builder = new OkHttpClient.Builder(); CookieJarImpl cookieJarImpl = new CookieJarImpl(new PersistentCookieStore(getApplicationContext())); builder.cookieJar(cookieJarImpl); okHttpClient = builder.build();
本文所涉及到的工程下載http://download.csdn.net/detail/u012702547/9599322