最近在做項目,甲方提出每次登錄都要輸入密碼,會很麻煩,要求實現(xiàn)一個記住登錄狀態(tài)的功能,于是便使用 Cookie 實現(xiàn)該功能
一、Cookie 簡介
Cookie,一種儲存在用戶本地終端上的數(shù)據(jù),有時也用其復數(shù)形式 Cookies。類型為“小型文本文件”,是某些網(wǎng)站為了辨別用戶身份,進行 Session 跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密),由用戶客戶端計算機暫時或永久保存的信息。
其實 Cookie 就是一個鍵和一個值構成的,隨著服務器端的響應發(fā)送給客戶端瀏覽器。然后客戶端瀏覽器會把 Cookie 保存起來,當下一次再訪問服務器時把 Cookie 再發(fā)送給服務器。
1、Cookie 是 HTTP 協(xié)議的規(guī)范之一,它是服務器和客戶端之間傳輸?shù)男?shù)據(jù)
2、首先由服務器通過響應頭把 Cookie 傳輸給客戶端,客戶端會將 Cookie 保存起來
3、當客戶端再次請求同一服務器時,客戶端會在請求頭中添加該服務器保存的 Cookie,發(fā)送給服務器
4、Cookie 就是服務器保存在客戶端的數(shù)據(jù)
5、Cookie 就是一個鍵值對
二、Cookie 使用
1、創(chuàng)建 Cookie
1
2
|
/ / Cookie 為鍵值對數(shù)據(jù)格式 Cookie cookie_username = new Cookie( "cookie_username" , username); |
2、設置 Cookie 持久時間
1
2
|
/ / 即:過期時間,單位是:秒(s) cookie_username.setMaxAge( 30 * 24 * 60 * 60 ); |
3、設置 Cookie 共享路徑
1
2
|
/ / 表示當前項目下都攜帶這個cookie cookie_username.setPath(request.getContextPath()); |
4、向客戶端發(fā)送 Cookie
1
2
|
/ / 使用 HttpServletResponse 對象向客戶端發(fā)送 Cookie response.addCookie(cookie_username); |
5、銷毀 Cookie
1
2
3
4
5
6
7
8
|
/ / 根據(jù) key 將 value 置空 Cookie cookie_username = new Cookie( "cookie_username" , ""); / / 設置持久時間為 0 cookie_username.setMaxAge( 0 ); / / 設置共享路徑 cookie_username.setPath(request.getContextPath()); / / 向客戶端發(fā)送 Cookie response.addCookie(cookie_username); |
三、進入正題
上面我們已經(jīng)了解了 Cookie 是什么,并且知道了 Cookie 的創(chuàng)建以及銷毀的方法,下面,我們就使用 Cookie 實現(xiàn)記住登錄狀態(tài)的功能,整個項目基于 SpringBoot 實現(xiàn)
1、注冊攔截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/** * 注冊攔截器 */ @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 請求路徑呢,原因是我們攔截登錄請求,當我們請求登錄界面時,我們已經(jīng)登錄過,那么我們就無需進入登錄界面,直接到主界面
我們使用了自定義的一個登錄攔截:LoginInterceptor,在第二步我們會詳細講解其中的實現(xiàn)原理
2、登錄攔截
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/** * 未登錄攔截器 */ @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已經(jīng)過期 Object obj = session.getAttribute(Const.SYSTEM_USER_SESSION); if ( null == obj) { // 根據(jù)用戶登錄賬號獲取數(shù)據(jù)庫中的用戶信息 UserInfo dbUser = dao.getUserInfoByAccount(cookie_username); // 將用戶保存到session中 session.setAttribute(Const.SYSTEM_USER_SESSION, dbUser); } // 已經(jīng)登錄 return true ; } } |
3、登錄請求
控制層
1
2
3
4
5
6
7
8
|
/** * 執(zhí)行登錄 */ @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(); } |
業(yè)務層
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
/** * 執(zhí)行登錄 */ 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; } // 判斷賬戶狀態(tài) if ( 1 != dbUser.getStatus()) { res.put( "msg" , "該賬號已被凍結,請聯(lián)系管理員" ); return res; } // 將登錄用戶信息保存到session中 session.setAttribute(Const.SYSTEM_USER_SESSION, dbUser); // 保存cookie,實現(xiàn)自動登錄 Cookie cookie_username = new Cookie( "cookie_username" , username); // 設置cookie的持久化時間,30天 cookie_username.setMaxAge( 30 * 24 * 60 * 60 ); // 設置為當前項目下都攜帶這個cookie cookie_username.setPath(request.getContextPath()); // 向客戶端發(fā)送cookie response.addCookie(cookie_username); res.put( "code" , 1 ); res.put( "msg" , "登錄成功" ); return res; } |
4、注銷登錄
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/** * 退出登錄 */ @RequestMapping (value = "logout" ) public String logout(HttpSession session, HttpServletRequest request, HttpServletResponse response) { // 刪除session里面的用戶信息 session.removeAttribute(Const.SYSTEM_USER_SESSION); // 保存cookie,實現(xiàn)自動登錄 Cookie cookie_username = new Cookie( "cookie_username" , "" ); // 設置cookie的持久化時間,0 cookie_username.setMaxAge( 0 ); // 設置為當前項目下都攜帶這個cookie cookie_username.setPath(request.getContextPath()); // 向客戶端發(fā)送cookie response.addCookie(cookie_username); return "login" ; } |
注銷登錄時,我們需要刪除 session 里面的用戶信息,刪除 cookie 里面的用戶信息,然后請求到登錄界面
四、總結
以上就是 SpringBoot 中使用 Cookie 實現(xiàn)記住登錄功能,在項目中還算是比較實用的功能,希望能對正在閱讀的你一點點幫助和啟發(fā),更多相關SpringBoot Cookie記住登錄內容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq_40065776/article/details/106998008