基于SpringBoot實現(xiàn)Web應用的登錄與退出功能
前言
登錄與退出功能作為 Web 應用中的基礎且重要的組成部分,直接關系到用戶的安全和隱私保護。通過實現(xiàn)登錄與退出功能,可以對用戶的身份進行驗證和授權,確保只有合法的用戶才能訪問特定的資源或執(zhí)行特定的操作。同時,退出功能也為用戶提供了便捷的方式來結束當前會話,保護其個人信息不被他人冒用。在完成 Spring Boot 前五章的學習后,下面簡單介紹使用 Spring Boot 實現(xiàn)登錄與退出的功能。
實現(xiàn)登錄功能
案例中選用 Spring Boot 3.0.2 作為整合、Thymeleaf 作為視圖、Spring Data JPA 作為持久層
簡單示例:
首先,創(chuàng)建新項目 SpringBootWebDemo ,勾選 Web 、MySQL 、Thymeleaf 和 JPA 的啟動器
然后,在 application.properties 全局配置文件中配置數(shù)據(jù)庫連接信息
#數(shù)據(jù)庫連接信息 spring.datasource.username=root spring.datasource.password=0123 spring.datasource.url=jdbc:mysql://localhost:3306/springbootwebdemo spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # SpringBoot 內部使用 SpringData , SpringData 的 JPA 是使用 Hibernate 實現(xiàn)的 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
接著,創(chuàng)建 Entity 包并在包內創(chuàng)建兩個實體類 User 和 Address
package cn.edu.SpringBootWebDemo.Entity; import jakarta.persistence.*; import java.util.Date; @Entity @Table(name = "user") public class User { private int id; private String username; private String password; private Date regDate; // 注冊日期 private Address address; // 地址 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Column(name = "reg_date") // 指定字段名 public Date getRegDate() { return regDate; } public void setRegDate(Date regDate) { this.regDate = regDate; } @ManyToOne // 假設:每一個用戶對應一個地址,一個地址可以對應多個用戶 @JoinColumn(name = "address_id") // 一般在多的這邊建立外鍵 public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", regDate=" + regDate + ", address=" + address + '}'; } }
package cn.edu.SpringBootWebDemo.Entity; import jakarta.persistence.*; @Entity @Table(name = "address") public class Address { private int id; private String addressInfo; // 地址詳情 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增 public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "address_info") // 指定字段名 public String getAddressInfo() { return addressInfo; } public void setAddressInfo(String addressInfo) { this.addressInfo = addressInfo; } @Override public String toString() { return "Address{" + "id=" + id + ", addressInfo='" + addressInfo + '\'' + '}'; } }
隨之,創(chuàng)建 Dao 包并在包內創(chuàng)建一個 UserDao 接口,繼承 JpaRepository<實體類,主鍵類型> ,并且聲明一個默認接口中沒有提供,需要根據(jù)用戶名查詢賬號的方法
package cn.edu.SpringBootWebDemo.Dao; import cn.edu.SpringBootWebDemo.Entity.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserDao extends JpaRepository<User,Integer> { // 默認接口中沒有提供根據(jù)用戶名查詢賬號的方法 public User getByUsername(String username); }
再創(chuàng)建 Service 包并在包內創(chuàng)建一個 UserService 接口,并創(chuàng)建該接口的實現(xiàn)類 UserServiceImpl
package cn.edu.SpringBootWebDemo.Service; import cn.edu.SpringBootWebDemo.Entity.User; public interface UserService { public User login(User user); }
package cn.edu.SpringBootWebDemo.Service; import cn.edu.SpringBootWebDemo.Dao.UserDao; import cn.edu.SpringBootWebDemo.Entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("userService") public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public User login(User user) { // 根據(jù)用戶名查詢有沒有對應的賬號 User user1 = userDao.getByUsername(user.getUsername()); // 判斷是否為空或密碼錯誤,登錄失敗返回 null if (user1 == null) return null; if(!user1.getPassword().equals(user.getPassword())) return null; // 返回 User 對象,登錄成功 return user1; } }
其次,創(chuàng)建 Controller 包并在包內創(chuàng)建一個 UserController 類
package cn.edu.SpringBootWebDemo.Controller; import cn.edu.SpringBootWebDemo.Entity.User; import cn.edu.SpringBootWebDemo.Service.UserService; import jakarta.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @Controller public class UserController { @Autowired private UserService userService; @GetMapping("/Login.html") public String login(HttpSession httpSession){ // 成功登錄后不能再返回登錄頁面,而是跳轉到主頁 boolean flag = httpSession.getAttribute("loginUser")==null?true:false; if (flag){ return "Login"; }else { return "redirect:/Main.html"; } } @GetMapping("/Main.html") public String main(){ return "Main"; } // 判斷登錄 @PostMapping("/Login.html") public String login(User user, HttpSession httpSession, Model model){ // 控制層——接受頁面的賬號和密碼。調用服務層的 login 方法,判斷登錄是否成功。 // 成功將返回的 user 對象保存到 session 的域空間;反之返回一個錯誤提示。 User user1 = userService.login(user); if(user1 != null) { // 將返回的 user 對象保存到 session 的域空間,頁面跳轉到主頁中 httpSession.setAttribute("loginUser",user1); return "redirect:/Main.html"; }else { // 登錄失敗,返回錯誤提示 model.addAttribute("loginError","用戶名或密碼錯誤!"); return "Login"; } } }
最后,在 resources/templates 目錄下創(chuàng)建兩個頁面 Login.html 和 Main.html ,再啟動 Spring Boot ,打開瀏覽器輸入 http://localhost:8080/Login.html 并按下回車鍵進行進行測試(啟動 Spring Boot 后,數(shù)據(jù)表會自動生成,但需自行插入一條信息進行測試)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>LoginDemo</title> </head> <body> <!-- loginError 不為空才顯示錯誤提示 --> <div style="color: red;" th:text="${loginError}" th:if="${not #strings.isEmpty(loginError)}"></div> <form th:action="@{/Login.html}" method="post"> 賬號:<input type="text" name="username" placeholder="請輸入賬號"> <br> 密碼:<input type="password" name="password" placeholder="請輸入密碼"> <br> <input style="margin-left: 54px;" type="submit" value="登錄"> </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>MainDemp</title> </head> <body> 登錄成功?。?! 主頁 </body> </html>
結果如圖:
1.登錄頁面
2.輸入賬號密碼,進行登錄
3.登錄成功,進入主頁
4.錯誤提示
配置攔截器
通常為了確保用戶在訪問需要認證的資源之前已經(jīng)登錄,需要在登錄功能中配置攔截器。
簡單示例:
首先,創(chuàng)建 Web 包并在包內創(chuàng)建一個 LoginFilter 類來自定義攔截器
package cn.edu.SpringBootWebDemo.Web; import cn.edu.SpringBootWebDemo.Entity.User; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; public class LoginFilter implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession httpSession = request.getSession(); // 從 session 的域空間獲取 user 對象 User user = (User) httpSession.getAttribute("loginUser"); if(user != null){ // 已登錄,放行 return true; }else { // 沒有登錄,不能訪問主頁面,出現(xiàn)提示信息 request.setAttribute("loginError","請登錄后再訪問!"); request.getRequestDispatcher("/Login.html").forward(request,response); return false; } } }
然后,創(chuàng)建 Configuration 包并在包內創(chuàng)建一個配置類 LoginFilterConfiguration ,將攔截器存放在配置類中,才能注冊到 Spring Boot 環(huán)境里
package cn.edu.SpringBootWebDemo.Configuration; import cn.edu.SpringBootWebDemo.Web.LoginFilter; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class LoginFilterConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 注冊自定義的攔截器,攔截所有請求,排除登錄頁面 registry.addInterceptor(new LoginFilter()) .addPathPatterns("/**") .excludePathPatterns("/Login.html"); // 在 Spring MVC 中,還需要排除靜態(tài)資源( *.css 、*.js 、*.jpg 等)攔截 // 在 Spring Boot 中,已設置排除,不需再添加 } }
最后,啟動 Spring Boot ,打開瀏覽器輸入 http://localhost:8080/Main.html 并按下回車鍵進行進行測試
結果如圖:
實現(xiàn)退出功能
在成功登錄后,通常用戶被重定向到主頁,而不是返回登錄頁面。同時,提供一個退出功能讓用戶能夠主動注銷并清除會話信息,也是必要的安全措施。
簡單示例:
首先,在 Main.html 中重新編寫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>MainDemo</title> </head> <body> 登錄成功!??!<br> <h3>主頁</h3> <br> <a th:href="@{/logout.html}" rel="external nofollow" >退出</a> </body> </html>
然后,在 UserController 類上添加一個退出的方法
// 退出 @GetMapping("/logout.html") public String logout(HttpSession httpSession){ // 通過 invalidate 方法清空 httpSession 里的內容 httpSession.invalidate(); return "redirect:/Login.html"; }
最后,啟動 Spring Boot ,打開瀏覽器輸入 http://localhost:8080/Login.html 并按下回車鍵進行進行測試
結果如圖:
成功登錄后,點擊退出便返回登錄頁面
以上就是基于SpringBoot實現(xiàn)Web應用的登錄與退出功能的詳細內容,更多關于SpringBoot登錄與退出的資料請關注腳本之家其它相關文章!
相關文章
spring aop底層源碼執(zhí)行邏輯剖析(源碼解析)
這篇文章主要介紹了spring aop底層源碼執(zhí)行邏輯剖析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-08-08一步步講解Spring?Boot整合MyBatis與PostgreSQL實戰(zhàn)指南
這篇文章主要介紹了如何在SpringBoot環(huán)境中集成MyBatis和PostgreSQL,涵蓋了環(huán)境搭建、項目創(chuàng)建、數(shù)據(jù)源配置、實體類與Mapper接口定義、MapperXML文件編寫、業(yè)務層與控制層實現(xiàn)以及測試與驗證的全過程,需要的朋友可以參考下2025-02-02