最近在做項目,甲方提出每次登錄都要輸入密碼,會很麻煩,要求實現一個記住登錄狀態的功能,於是便使用 Cookie 實現該功能
一、Cookie 簡介
Cookie,一種儲存在用戶本地終端上的數據,有時也用其複數形式 Cookies。類型爲“小型文本文件”,是某些網站爲了辨別用戶身份,進行 Session 跟蹤而儲存在用戶本地終端上的數據(通常經過加密),由用戶客戶端計算機暫時或永久保存的信息。
其實 Cookie 就是一個鍵和一個值構成的,隨着服務器端的響應發送給客戶端瀏覽器。然後客戶端瀏覽器會把 Cookie 保存起來,當下一次再訪問服務器時把 Cookie 再發送給服務器。
1、Cookie 是 HTTP 協議的規範之一,它是服務器和客戶端之間傳輸的小數據
2、首先由服務器通過響應頭把 Cookie 傳輸給客戶端,客戶端會將 Cookie 保存起來
3、當客戶端再次請求同一服務器時,客戶端會在請求頭中添加該服務器保存的 Cookie,發送給服務器
4、Cookie 就是服務器保存在客戶端的數據
5、Cookie 就是一個鍵值對
二、Cookie 使用
1、創建 Cookie
// Cookie 爲鍵值對數據格式
Cookie cookie_username = new Cookie("cookie_username", username);
2、設置 Cookie 持久時間
// 即:過期時間,單位是:秒(s)
cookie_username.setMaxAge(30 * 24 * 60 * 60);
3、設置 Cookie 共享路徑
// 表示當前項目下都攜帶這個cookie
cookie_username.setPath(request.getContextPath());
4、向客戶端發送 Cookie
// 使用 HttpServletResponse 對象向客戶端發送 Cookie
response.addCookie(cookie_username);
5、銷燬 Cookie
// 根據 key 將 value 置空
Cookie cookie_username = new Cookie("cookie_username", "");
// 設置持久時間爲0
cookie_username.setMaxAge(0);
// 設置共享路徑
cookie_username.setPath(request.getContextPath());
// 向客戶端發送 Cookie
response.addCookie(cookie_username);
三、進入正題
上面我們已經瞭解了 Cookie 是什麼,並且知道了 Cookie 的創建以及銷燬的方法,下面,我們就使用 Cookie 實現記住登錄狀態的功能,整個項目基於 SpringBoot 實現
1、註冊攔截器
/**
* 註冊攔截器
*/
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration ir = registry.addInterceptor(loginHandlerInterceptor);
// 攔截路徑
ir.addPathPatterns("/*");
// 不攔截路徑
List<String> irs = new ArrayList<String>();
irs.add("/api/*");
irs.add("/wechat/*");
irs.add("/oauth");
ir.excludePathPatterns(irs);
}
}
我們攔截了所有的請求路徑,放開了 api、wechat 等請求路徑
這裏可能會有一個疑問,爲什麼不放開請求登錄界面的 api 請求路徑呢,原因是我們攔截登錄請求,當我們請求登錄界面時,我們已經登錄過,那麼我們就無需進入登錄界面,直接到主界面
我們使用了自定義的一個登錄攔截:LoginInterceptor,在第二步我們會詳細講解其中的實現原理
2、登錄攔截
/**
* 未登錄攔截器
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private LoginDao dao;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 獲得cookie
Cookie[] cookies = request.getCookies();
// 沒有cookie信息,則重定向到登錄界面
if (null == cookies) {
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
// 定義cookie_username,用戶的一些登錄信息,例如:用戶名,密碼等
String cookie_username = null;
// 獲取cookie裏面的一些用戶信息
for (Cookie item : cookies) {
if ("cookie_username".equals(item.getName())) {
cookie_username = item.getValue();
break;
}
}
// 如果cookie裏面沒有包含用戶的一些登錄信息,則重定向到登錄界面
if (StringUtils.isEmpty(cookie_username)) {
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
// 獲取HttpSession對象
HttpSession session = request.getSession();
// 獲取我們登錄後存在session中的用戶信息,如果爲空,表示session已經過期
Object obj = session.getAttribute(Const.SYSTEM_USER_SESSION);
if (null == obj) {
// 根據用戶登錄賬號獲取數據庫中的用戶信息
UserInfo dbUser = dao.getUserInfoByAccount(cookie_username);
// 將用戶保存到session中
session.setAttribute(Const.SYSTEM_USER_SESSION, dbUser);
}
// 已經登錄
return true;
}
}
3、登錄請求
控制層
/**
* 執行登錄
*/
@PostMapping("login")
@ResponseBody
public String login(String username, String password, HttpSession session, HttpServletRequest request, HttpServletResponse response) {
return service.doLogin(username.trim(), password.trim(), session, request, response).toJSONString();
}
業務層
/**
* 執行登錄
*/
public JSONObject doLogin(String username, String password, HttpSession session, HttpServletRequest request, HttpServletResponse response) {
// 最終返回的對象
JSONObject res = new JSONObject();
res.put("code", 0);
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
res.put("msg", "請輸入手機號或密碼");
return res;
}
UserInfo dbUser = dao.getUserInfoByAccount(username);
if (null == dbUser) {
res.put("msg", "該賬號不存在,請檢查後重試");
return res;
}
// 驗證密碼是否正確
String newPassword = PasswordUtils.getMd5(password, username, dbUser.getSalt());
if (!newPassword.equals(dbUser.getPassword())) {
res.put("msg", "手機號或密碼錯誤,請檢查後重試");
return res;
}
// 判斷賬戶狀態
if (1 != dbUser.getStatus()) {
res.put("msg", "該賬號已被凍結,請聯繫管理員");
return res;
}
// 將登錄用戶信息保存到session中
session.setAttribute(Const.SYSTEM_USER_SESSION, dbUser);
// 保存cookie,實現自動登錄
Cookie cookie_username = new Cookie("cookie_username", username);
// 設置cookie的持久化時間,30天
cookie_username.setMaxAge(30 * 24 * 60 * 60);
// 設置爲當前項目下都攜帶這個cookie
cookie_username.setPath(request.getContextPath());
// 向客戶端發送cookie
response.addCookie(cookie_username);
res.put("code", 1);
res.put("msg", "登錄成功");
return res;
}
4、註銷登錄
/**
* 退出登錄
*/
@RequestMapping(value = "logout")
public String logout(HttpSession session, HttpServletRequest request, HttpServletResponse response) {
// 刪除session裏面的用戶信息
session.removeAttribute(Const.SYSTEM_USER_SESSION);
// 保存cookie,實現自動登錄
Cookie cookie_username = new Cookie("cookie_username", "");
// 設置cookie的持久化時間,0
cookie_username.setMaxAge(0);
// 設置爲當前項目下都攜帶這個cookie
cookie_username.setPath(request.getContextPath());
// 向客戶端發送cookie
response.addCookie(cookie_username);
return "login";
}
註銷登錄時,我們需要刪除 session 裏面的用戶信息,刪除 cookie 裏面的用戶信息,然後請求到登錄界面
四、總結
以上就是 SpringBoot 中使用 Cookie 實現記住登錄功能,在項目中還算是比較實用的功能,希望能對正在閱讀的你一點點幫助和啓發
如您在閱讀中發現不足,歡迎留言!!!