基于SpringBoot实现Web应用的登录与退出功能
作者:啊Q老师
前言
登录与退出功能作为 Web 应用中的基础且重要的组成部分,直接关系到用户的安全和隐私保护。通过实现登录与退出功能,可以对用户的身份进行验证和授权,确保只有合法的用户才能访问特定的资源或执行特定的操作。同时,退出功能也为用户提供了便捷的方式来结束当前会话,保护其个人信息不被他人冒用。在完成 Spring Boot 前五章的学习后,下面简单介绍使用 Spring Boot 实现登录与退出的功能。
实现登录功能
案例中选用 Spring Boot 3.0.2 作为整合、Thymeleaf 作为视图、Spring Data JPA 作为持久层
简单示例:
首先,创建新项目 SpringBootWebDemo ,勾选 Web 、MySQL 、Thymeleaf 和 JPA 的启动器
然后,在 application.properties 全局配置文件中配置数据库连接信息
#数据库连接信息 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 实现的 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
接着,创建 Entity 包并在包内创建两个实体类 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 + '\'' + '}'; } }
随之,创建 Dao 包并在包内创建一个 UserDao 接口,继承 JpaRepository<实体类,主键类型> ,并且声明一个默认接口中没有提供,需要根据用户名查询账号的方法
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> { // 默认接口中没有提供根据用户名查询账号的方法 public User getByUsername(String username); }
再创建 Service 包并在包内创建一个 UserService 接口,并创建该接口的实现类 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) { // 根据用户名查询有没有对应的账号 User user1 = userDao.getByUsername(user.getUsername()); // 判断是否为空或密码错误,登录失败返回 null if (user1 == null) return null; if(!user1.getPassword().equals(user.getPassword())) return null; // 返回 User 对象,登录成功 return user1; } }
其次,创建 Controller 包并在包内创建一个 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 目录下创建两个页面 Login.html 和 Main.html ,再启动 Spring Boot ,打开浏览器输入 http://localhost:8080/Login.html 并按下回车键进行进行测试(启动 Spring Boot 后,数据表会自动生成,但需自行插入一条信息进行测试)
<!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.错误提示
配置拦截器
通常为了确保用户在访问需要认证的资源之前已经登录,需要在登录功能中配置拦截器。
简单示例:
首先,创建 Web 包并在包内创建一个 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 { // 没有登录,不能访问主页面,出现提示信息 request.setAttribute("loginError","请登录后再访问!"); request.getRequestDispatcher("/Login.html").forward(request,response); return false; } } }
然后,创建 Configuration 包并在包内创建一个配置类 LoginFilterConfiguration ,将拦截器存放在配置类中,才能注册到 Spring Boot 环境里
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 中,还需要排除静态资源( *.css 、*.js 、*.jpg 等)拦截 // 在 Spring Boot 中,已设置排除,不需再添加 } }
最后,启动 Spring Boot ,打开浏览器输入 http://localhost:8080/Main.html 并按下回车键进行进行测试
结果如图:
实现退出功能
在成功登录后,通常用户被重定向到主页,而不是返回登录页面。同时,提供一个退出功能让用户能够主动注销并清除会话信息,也是必要的安全措施。
简单示例:
首先,在 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实现Web应用的登录与退出功能的详细内容,更多关于SpringBoot登录与退出的资料请关注脚本之家其它相关文章!