基於RFC6265 (HTTP狀態管理協議)實現簡單的登入系統

來源:互聯網
上載者:User

該協議主要是闡述如何利用HTTP Cookie與SetCookie頭欄位來實現對HTTP Request

狀態的跟蹤與管理,這個在使用者行為分析,登入系統設計等方法有著很重要的應用。對

於大多數現代的瀏覽器都支援RFC6265.

 

基本原理:

RFC6265闡述通過設定SetCookie不同值在HTTPResponse中,來告訴瀏覽器用戶端在

接下來的每次請求Request Header中都帶上Response中指定的值與行為。直到伺服器

配置的session到期為止。通過Tomcat配置session到期時間為30分鐘,在web.xml配置

檔案中可以重寫該屬性值。同時當使用者關閉瀏覽器以後,在用戶端記憶體中對於該網站

的cookie內容將會自動銷毀。也許這樣不太方便使用者,於是很多網站提供了記住自己帳

號的原因,其實就是通過將cookie寫到本地檔案中。

 

系統訪問與重新導向到登入頁面

首先當瀏覽器用戶端發起一個Request請求訪問指定URL或者Web Server時,伺服器

端通過檢查要求標頭是否含有Cookie欄位,以及Cookie欄位中的內容來設別訪問者是否

為登入或者未登入使用者,如果是未登入頁面,則將URL重新導向到登入頁面即可。使用者

登入以後伺服器端發送一個HTTP Response + Set-Cookie內容到用戶端瀏覽器,那麼

在隨後所有發往該Domain的URL都將會帶上Set-Cookie中指定的內容,HTTP 

Request + Cookie到伺服器端,伺服器端通過檢查Request 頭中Cookie內容實現對

使用者的狀態追蹤。從而將無狀態HTTP Request變成一個有狀態的HTTP串連加以

管理。登入處理基本的流程圖如下:


伺服器與用戶端HTTP Request發送與接受狀態:


使用者退出系統與Request狀態終止

當用戶端關閉瀏覽器時候,用戶端Cookie將會被自動從記憶體中丟棄,當用戶端再次打

開瀏覽器請求伺服器端資源時候,將被要求再次登入到伺服器端建立新的可跟蹤的

Request 會話當超過伺服器端配置的會話時間時,同樣會要求使用者再次登入系統。

當使用者使用系統退出功能正常退出時,當退出時候通過設定Max-Age : 0來remove

當前cookie內容實現對用戶端狀態的清零。只要在HTTP Response中加上Cookie過

期屬性同時設定一個過去的時間。例子如下:


RFC6265中關於Cookie與SetCookie的屬性與使用詳解

Cookie

SetCookie

包含於HTTP Request Header,使用者用戶端向伺服器端發送驗證資訊與其它有用資訊,主要用來跟蹤用戶端狀態與分析使用者行為

在HTTP Response中設定,主要用於伺服器端向用戶端發送指定的狀態資訊,建立與用戶端的聯絡。通過設定HTTPOnly屬性與Secure屬性還可以保護用戶端Cookie資料,減少惡意讀取使用者Cookie資訊發生。

RFC6265中一個簡單例子:

== Server -> UserAgent == // 伺服器發送到用戶端

Set-Cookie:SID=31d4d96e407aad42

== User Agent ->Server == // 每個請求中都會帶上SID資訊,實現追蹤使用者狀態

Cookie: SID=31d4d96e407aad42

要求用戶端的所有請求路徑都要帶上SID資訊,通過發送Path=/實現

== Server -> UserAgent ==

Set-Cookie:SID=31d4d96e407aad42; Path=/; Domain=example.com

== User Agent ->Server ==

Cookie: SID=31d4d96e407aad42

刪除用戶端Request Cookie中SID資訊,取目前時間以前的一個任意時間。

== Server -> UserAgent ==

Set-Cookie: SID=;Expires=Sun, 06 Nov 1994 08:49:37 GMT

最後來看一看我抓取的CSDN登入以後的Cookie資訊:

J2EE 當從HTTP Servlet Request中調用擷取SessionID方法以後會自動把JSESSIONID

作為Cookie設定到Response頭中。所以無需顯式再次調用!

根據RFC6265的內容,基於Spring3 MVC我自己也實現了一個簡單的登入系統設計

可以協助大家更好的理解協議。只有兩個頁面,兩個Controller類與一個ServletFilter

各個類的作用大致如下:

ServletFilter類:實現對HTTP Request頭的檢查,跟蹤使用者狀態

兩個Controller類:一個用來系統管理使用者登入登出,一個是簡單的擷取首頁面資訊

其中ServletFilter類代碼如下:

package com.edinme.exam.filter;import java.io.IOException;import java.util.Date;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.editme.exam.util.FilterUtil;public class SingleSignOnFilter implements Filter{ @Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;String ipAddress = httpRequest.getRemoteAddr();// get URI resource pathString uriPath = httpRequest.getRequestURI();String contextPath = httpRequest.getContextPath();String cookie = httpRequest.getHeader("Cookie");String sessionId = httpRequest.getSession().getId(); // enable SetCookie header in HTTP Responseif(FilterUtil.validURLRequest(uriPath, cookie, contextPath, sessionId)){System.out.println("Request URI : " + uriPath);System.out.println("IP "+ipAddress + ", Time " + new Date().toString());chain.doFilter(request, response);}else{System.out.println(httpRequest.getProtocol() + httpRequest.getLocalPort() + httpRequest.getContextPath());httpResponse.sendRedirect("/exam/user.do");}}@Overridepublic void init(FilterConfig config) throws ServletException {// TODO Auto-generated method stub}}
使用者登入登出Controller:

package com.edinme.exam.controller;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.ModelAndView;import com.edinme.exam.dto.MockUpDataFactory;import com.edinme.exam.dto.UserDto;import com.editme.exam.util.FilterUtil;@Controller@RequestMapping(value = "/user")public class UserLoginController {@RequestMapping(method = RequestMethod.GET)public ModelAndView goLoginPage(){System.out.println("Dispaly SSO Page");ModelAndView view = new ModelAndView("user");return view;}@RequestMapping(value = "signIn", method = RequestMethod.GET)@ResponseBodypublic UserDto login(@RequestParam String userId, @RequestParam String password, /*HttpServletRequest httpRequest,*/ HttpServletResponse response){System.out.println("User Name = " + userId);MockUpDataFactory dataFactory = new MockUpDataFactory();response.addHeader("Set-Cookie", "userId=" + userId + "; Path=" + FilterUtil.CONTEXT_PATH + "; HttpOnly");return dataFactory.getUserById(userId);}@RequestMapping(value = "signOut", method = RequestMethod.GET)@ResponseBodypublic UserDto logout(@RequestParam String userId, HttpServletRequest httpRequest, HttpServletResponse response){MockUpDataFactory dataFactory = new MockUpDataFactory();//Set-Cookie:JSESSIONID=delete; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/exam///Set-Cookie:userId=delete; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/exam/Cookie[] cs = httpRequest.getCookies();for(Cookie c : cs){c.setMaxAge(0); // set expire attributec.setValue("delete");c.setPath(FilterUtil.CONTEXT_PATH); // set path, must be same as login context pathresponse.addCookie(c);}response.setHeader("Expires", "Thu, 19 Nov 1981 08:52:00 GMT"); // must be GTM formatreturn dataFactory.getUserById(userId);}////public static void main(String[] args)//{//SimpleDateFormat sdf = new SimpleDateFormat("E dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);//sdf.setTimeZone(TimeZone.getTimeZone("GMT"));//System.out.println(sdf.format(new Date()));//}}
全部原始碼下載點擊這裡:

http://download.csdn.net/detail/jia20003/7087947

覺得好請頂一下啊!!,謝謝!!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.