HTTP/1.1 使用的認證方式有
1)BASIC 認證(基本認證);
2)DIGEST 認證(摘要認證);
3)SSL 客戶端認證;
4)FormBase 認證(基於表單認證);
本文目錄:
1、基於表單認證
2、基於表單認證一般會使用Cookie 來管理 Session(會話)
3、Java + SpringBoot 簡單演示表單登陸
4、測試
1、基於表單認證 <-- 返回目錄
基於表單的認證方法並不是 HTTP 協議中定義的 。客戶端會向服務器上的 Web 應用程序發送登陸信息,按登陸信息的驗證結果認證。根據 Web 應用程序的實際安裝,提供的用戶界面及認證方式也各不相同。多數情況下,輸入用戶名 ID 和密碼等登陸信息后,發送給 Web 應用程序,基於認證結果來決定認證是否成功。
由於使用上的便利性及安全性問題,HTTP 協議標准提供的 BASIC 認證和 DIGEST 認證幾乎不怎么使用。另外,SSL 客戶端認證雖然具有高度的安全等級,但因為導入及維持費用等問題,還尚未普及。
不具備共同標准規范的表單認證,在每個 Web 網站上會有各自不同的實現方式。如果時全面考慮過安全性能而實現的表單認證,那么就能夠具備高度的安全等級。
2、基於表單認證一般會使用Cookie 來管理 Session(會話) <-- 返回目錄
基於表單認證本身是通過服務器端的 Web 應用,將客戶端發送過來的用戶 ID 和密碼進行校驗。但鑒於 HTTP 是無狀態協議,之前已認證成功的用戶狀態無法通過協議層面保存下來。即無法實現狀態管理,因此即使當該用戶下一次繼續訪問,也無法區分他與其他的用戶。於是我們會使用 Cookie 來管理 Session,以彌補 HTTP 協議中不存在的狀態管理功能。

步驟1:客戶端把用戶 ID 和密碼等登陸信息放到報文的實體部分,通常是以 POST 方法把請求發送給服務器。而這時,會使用 HTTPS 通信來進行 HTML 表單頁面的顯示和用戶輸入數據的傳輸。
步驟2:服務器會發放用以標識用戶的 Sesssion ID。通過驗證從客戶端發送過來的登陸信息進行身份認證,然后把用戶的認證狀態與 Session ID 綁定后記錄在服務器端。
向客戶端返回響應時,會在首部字段 Set-Cookie 內寫入 Session ID(如 PHPSESSID=028a8c...)。然而,如果 Session ID 被第三方盜走,對方就可以偽裝成你的身份進行惡意操作了。因此必須防止 Session ID 被盜,或被猜出。為了做到這點,Session ID 應使用難以推測的字符串,且服務器端也需要進行有效期的管理,保證其安全性。另外,為減輕跨站腳本攻擊(XSS)造成的損失,建議事先在 Cookie 內加上 httponly 屬性。
3、Java + SpringBoot 簡單演示表單登陸 <-- 返回目錄

依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
Controller
package com.oy.controller; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; 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; @Controller public class IndexController { /** * 訪問登陸頁面 * @param req * @param res * @return */ @RequestMapping(value = "/login", method = RequestMethod.GET) public String login(HttpServletRequest req, HttpServletResponse res) { return "login"; } /** * 登陸 * @param req * @param res * @return */ @RequestMapping(value = "/login", method = RequestMethod.POST) @ResponseBody public String doLogin(HttpServletRequest req, HttpServletResponse res, @RequestParam(value = "username", required = true) String username, @RequestParam(value = "password", required = true) String password) { // 校驗用戶名和密碼 if (!"test".equals(username) || !"123456".equals(password)) { return "{code: 40502, msg: \"用戶名或密碼錯誤\"}"; } HttpSession session = req.getSession(); session.setAttribute("uid", 101); session.setAttribute("username", "test"); session.setAttribute("status", 0); return "{code: 0, data: {uid:\"101\", username:\"test\"}}"; } @RequestMapping("/userinfo") @ResponseBody public String getUserInfo(HttpServletRequest req, HttpServletResponse res) { Cookie[] cs = req.getCookies(); if (cs != null && cs.length > 0) { for (Cookie c : cs) { System.out.println(c.getName() + " = " + c.getValue()); } } HttpSession session = req.getSession(); Integer uid = (Integer) session.getAttribute("uid"); if (uid == null) { res.setStatus(401); return "{code: 401, msg: \"請登錄\"}"; } return "{userinfo: {uid:\"101\", username:\"test\"}}"; } }
4、測試 <-- 返回目錄
1)首先訪問 http://localhost:8089/BootDemo/userinfo,結果

2)訪問 http://localhost:8089/BootDemo/login, 彈出登陸頁面

3)登陸成功

4)再次訪問 http://localhost:8089/BootDemo/userinfo

---
