JavaWeb應用如何實現保持登入狀態
做JavaWeb開發,難免會遇到登入系統保持登入狀態的問題?比如說我登入過後關閉瀏覽器,下次再訪問相同的網站,預設會顯示已登入狀態,一段時間內就不必再重新登入了;再比如站在後臺介面設計的角度去考慮,使用者登入後,做了一系列的使用者操作介面,那麼這些介面不可能都帶上一個userid的欄位吧,這樣不僅開發麻煩,而且容易被黑客攻擊。那麼如何解決這些問題呢?那就是通過代理服務對客戶端請求的攔截來實現,經過驗證後才開始執行業務邏輯。
如何搭建代理服務的過程,這裡就不詳細介紹了,我們以實現保持登入狀態為例,實現原理大概是這樣子的:
1.客戶端請求後臺登入介面。
2.後臺驗證通過後,將使用者的登入狀態儲存至cookie並寫入客戶端。
3.客戶端再次登入網站,請求login介面時,後臺直接從客戶端獲取到該使用者寫入cookie的登入狀態。
4.通過對該狀態的驗證,確認使用者是否需要再次登入。
5.如cookie過期,則跳轉至登入頁;如未過期,則直接顯示為已登入狀態。
這裡前端js用ajax請求即可,如請求一個url地址:
我們要注意一點,在請求成功後的Response Headers中,有Set-Cookie一項,設定一個key為java,value為myJavaData的Map值,這個是重點,有這個值客戶端就會自動把這個Map值設為cookie值,這就是我們所說的登入狀態loginState,如下圖所示:
那麼這個Set-Cookie一項資料怎麼來呢?是通過Java後臺設定的,原始碼如下:
這樣一來,就實現了在後臺服務端為客戶端設定cookie的功能,使用者在下次請求相同域的介面時,java後臺只需// 設定格式 response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST"); response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type"); response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); // 建立Cookie Cookie cookie = new Cookie("java", "myJavaData"); // 有效期,秒為單位 cookie.setMaxAge(3600); // 設定cookie response.addCookie(cookie); response.getWriter().print("cookie建立成功");
// 獲取客戶端cookie
request.setCharacterEncoding("utf-8");
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
System.out.println(c.getName() + "--->" + c.getValue());
}
}
即可獲取客戶端的登入狀態,從而做出響應操作。(注)此處的cookie值無需客戶端專門帶入,會隨請求自動傳輸到後臺。上例中的setMaxAge即為登入狀態的有效期設定點。
還有一種業務狀態是希望,使用者只要關閉了瀏覽器,該登入狀態就會清除,下次開啟瀏覽器必須重新登入,如CSDN部落格登入即使如此。
這種情況我們可以使用session會話實現:
java後臺設定session程式碼
// 設定格式
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
// 使用request物件的getSession()獲取session,如果session不存在則建立一個
HttpSession session = request.getSession();
// 將資料儲存到session中
session.setAttribute("java", "myJavaData");
// 獲取session的Id
String sessionId = session.getId();
// 判斷session是不是新建立的
if (session.isNew()) {
response.getWriter().print("session建立成功,session的id是:" + sessionId);
} else {
System.out.println(session.getAttribute("java")); // 值myJavaData
response.getWriter().print(
"伺服器已經存在該session了,session的id是:" + sessionId);
}
客戶端請求後,Set-Cookie一項同樣具備了值:當然,上面只是舉了一些簡單的例子,在實際應用中不可能只儲存一個loginState這麼簡單,還會儲存如OSS_COOKIES等安全驗證欄位,以上實現都是在請求與頁面同域的情況下。如果想要跨域實現,即客戶端與後臺不在同一個域名下,則通過JSONP實現。