精讀大型網站架構的技術細節:後端架構規整化Cookie和Session

程序員高級碼農ii 發佈 2022-11-26T22:45:06.244101+00:00

Cookie和Session接口請求(HTTP請求)是無狀態的,每次請求都是完全獨立的。也就是說,在處理請求時,Web應用伺服器無法得知這個請求是哪個用戶發送的,無法跟蹤上一次請求的狀態。

Cookie和Session

接口請求(HTTP請求)是無狀態的,每次請求都是完全獨立的。也就是說,在處理請求時,Web應用伺服器無法得知這個請求是哪個用戶發送的,無法跟蹤上一次請求的狀態。但是,有些時候接口請求需要記錄一些狀態,例如,在伺服器處理接口A時,需要檢查請求用戶是否已經登錄,而登錄接口是接口B。對於這類問題,一般使用Cookie和Session解決。

1.Cookie

Cookie是解決接口請求無狀態問題的有效手段,後端應用程式可以在響應報文的Header信息中添加Set-Cookie屬性,當客戶端(一般是瀏覽器)接收到響應報文時,會記錄Set-Cookie的值,當下次發送請求時,會自動地把SetCookie的值放到請求報文里。也就是說,接口請求的狀態(如用戶登錄標識)可以存放在客戶端,客戶端請求時會主動攜帶這些狀態。Cookie的工作原理如圖4.57所示。

注意:客戶端自動保存Cookie是不絕對的,如果瀏覽器設置了阻止Cookie的話,Cookie是不會自動被保存的。前端頁面需要提示用戶解除「阻止Cookie」(如果用戶阻止了Cookie的話)。另外,在客戶端自動保存Cookie的情況下,不同域名會有不同的存儲空間,A域名的Cookie是不會自動填到B域名的請求中的。

在以Spring Boot為基礎框架的後端應用程式中,向響應報文的Header信息中添加Set-Cookie屬性的代碼如代碼4.27所示,其中,代碼中的函數為Controller層中的接口的入口函數,xxx是Cookie的名,yyy是Cookie的值。

代碼4.27 後端應用程式添加Cookie信息

@Controller

@RequestMapping(value="/test",method = RequestMethod.POST)

@ResponseBody

public JSONObject create(@RequestBody String requestParam, HttpServlet

Response response) {

//向響應報文的Header信息中添加Set-Cookie屬性

response.addCookie(new Cookie("xxx", "yyy"));

}

另外,後端應用程式從請求報文的Header信息中獲取Cookie值的代碼如代碼4.28所示,其中,代碼中的函數為Controller層中的接口的入口函數,@CookieValue("xxx")表示通過註解自動尋找xxx對應的Cookie值。

代碼4.28 後端應用程式獲取Cookie信息

@Controller

@RequestMapping(value="/test",method = RequestMethod.GET)

@ResponseBody

public JSONObject get(HttpServletRequest request, @CookieValue("xxx")

String yyy) {

}

「以Cookie的方式解決請求無狀態問題」有一個很嚴重的缺陷,那就是安全性的問題,如客戶端可以偽造登錄信息等。因此,狀態信息不能只存在客戶端上,伺服器上也需要想辦法保存狀態信息。

2.Session

Session是伺服器記錄狀態信息的手段,後端應用程式可以建立一個Session(會話,其實就是一片存儲空間),並向Session中存放一些狀態信息(如用戶ID、用戶權限標識等),Web應用伺服器軟體會對應創建一個Session對象和生成對應的Session ID,並且將其存放到公共的Session存儲空間當中。當請求處理結束時,Web應用伺服器會自動將Session ID添加到響應報文的Header信息的Set-Cookie屬性當中。客戶端(一般是瀏覽器)接收到響應報文後,會自動保存Session ID,當下次發送請求時,會自動把Session ID放到請求報文當中,伺服器接收到請求後,後端應用程式就可以根據Session ID獲取到對應的會話信息了。

注意:雖然Session信息保存在伺服器上,但是Session是不能脫離Cookie而單獨使用的。因為後端應用程式需要Cookie信息中的Session ID才能獲取對應的Session信息。

如果後端應用程式需要使用Session的話,是不需要手動設置或獲取Header信息的(自動完成),只需要操作Session即可。添加Session值和獲取Session值的代碼如代碼4.29所示,其中,代碼中的函數為Controller層中的接口的入口函數,aaa是Session信息的名,bbb是對應的值。

代碼4.29 後端應用程式操作Session

@Controller

@RequestMapping(value="/test",method = RequestMethod.POST)

@ResponseBody

public JSONObject create(@RequestBody String requestParam, HttpServlet

Request request) {

//設置Session信息

request.getSession().setAttribute("aaa", "bbb");

//獲取Session信息

String sessionValue = request.getSession().getAttribute("aaa");

//刪除Session信息

request.getSession().removeAttribute("aaa");

}

另外,由於Session本質上只是保存在伺服器上數據,而不能跟蹤用戶的連接情況,所以在一般情況下,都需要設置一個Session過期時間。在使用Spring Boot框架的後端應用程式當中,Session過期時間的設置在配置文件(默認是application.properties)當中,如代碼4.30所示。

代碼4.30 在配置文件中設置Session過期時間

#設置Session過期時間為1小時

server.servlet.session.timeout=3600s

3.Cookie和Session的使用場景

由於Cookie的安全性不高,所以一般不單獨使用Cookie。而Session一般用作用戶信息的記錄,如是否已登錄、用戶ID、用戶權限等。利用Session,可以幫助接口做用戶鑒權。

本文給大家講解的內容是大型網站架構的技術細節:後端架構規整化Cookie和Session

  1. 下篇文章給大家講解的內容是大型網站架構的技術細節:後端架構規整化應用拆分和協調
  2. 覺得文章不錯的朋友可以轉發此文關注小編;
  3. 感謝大家的支持
關鍵字: