使用 Spring Boot、MyBatis Plus、Mysql实现用户登录和"记住我"功能
实现用户登录和"记住我"功能涉及到Spring Boot作为框架,MyBatis-Plus作为持久层框架,以及MySQL作为数据库。下面是一个简单的示例代码以及核心算法说明。
创建数据库表
首先,创建一个名为 rm_user 的数据库表,用于存储用户信息。
sql
CREATE TABLE rm_user (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
remember_token VARCHAR(100),
UNIQUE KEY unique_username (username)
);
初始化管理员帐号
INSERT INTO `rm_user` (`id`, `username`, `password`, `remember_token`)
VALUES
(1000, 'admin', '123456', NULL);
依赖配置:
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>com.baomidougroupId>
artifactId>mybatis-plus-boot-starterartifactId>
version>3.4.3version>
dependency>
dependency>
groupId>mysqlgroupId>
artifactId>mysql-connector-javaartifactId>
dependency>
dependencies>
application.properties配置:
# MySQL Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name
spring.datasource.username=your_database_username
spring.datasource.password=your_database_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis Plus Configuration
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
创建 RmUser 实体类
创建一个名为 RmUser 的实体类,用于映射数据库表中的用户信息。
package com.icoderoad.example.demo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("rm_user")
public class RmUser {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String rememberToken;
}
创建 RmUserMapper
使用 MyBatis-Plus 创建一个 RmUserMapper 接口,用于数据库操作。
package com.icoderoad.example.demo.mapper;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.icoderoad.example.demo.entity.RmUser;
@Repository
public interface RmUserMapper extends BaseMapper
{ }
创建 RmUserService
创建一个 RmUserService 类,处理用户登录和"记住我"功能。
package com.icoderoad.example.demo.service;
import java.util.UUID;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.icoderoad.example.demo.entity.RmUser;
import com.icoderoad.example.demo.mapper.RmUserMapper;
public class RmUserService {
private RmUserMapper userMapper;
public boolean login(String username, String password, boolean rememberMe,
HttpServletRequest request, HttpServletResponse response) {
RmUser user = userMapper.selectOne(new QueryWrapper
().eq("username", username)); if (user != null && user.getPassword().equals(password)) {
// 登录成功
if (rememberMe) {
// 生成一个随机的rememberToken
String rememberToken = UUID.randomUUID().toString();
user.setRememberToken(rememberToken);
userMapper.updateById(user);
// 将rememberToken存储到Cookie中
Cookie rememberMeCookie = new Cookie("rememberMe", rememberToken);
rememberMeCookie.setMaxAge(7 * 24 * 60 * 60); // 设置Cookie有效期为7天
response.addCookie(rememberMeCookie);
}
// 在Session中保存登录状态
request.getSession().setAttribute("user", user);
return true;
}
return false;
}
public void logout(HttpServletRequest request, HttpServletResponse response) {
// 清除Session中的用户信息
request.getSession().removeAttribute("user");
// 清除记住我功能的Cookie
Cookie rememberMeCookie = new Cookie("rememberMe", null);
rememberMeCookie.setMaxAge(0);
response.addCookie(rememberMeCookie);
}
public RmUser getUserFromRememberMeCookie(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("rememberMe".equals(cookie.getName())) {
String rememberToken = cookie.getValue();
if (!StringUtils.isEmpty(rememberToken)) {
return userMapper.selectOne(new QueryWrapper
().eq("remember_token", rememberToken)); }
}
}
}
return null;
}
}
创建 RmUserController
创建一个 RmUserController 类,处理用户相关的HTTP请求。
package com.icoderoad.example.demo.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.icoderoad.example.demo.entity.RmUser;
import com.icoderoad.example.demo.service.RmUserService;
public class RmUserController {
private RmUserService userService;
public String loginPage( HttpServletRequest request ) {
RmUser user = (RmUser) request.getSession().getAttribute("user");
if (user == null) {
user = userService.getUserFromRememberMeCookie(request);
}
if( user !=null ) {
return "redirect:/rm/dashboard";
}
return "rm/login";
}
public String login( String username, String password,
boolean rememberMe,
HttpServletRequest request, HttpServletResponse response, Model model) {
boolean loginResult = userService.login(username, password, rememberMe, request, response);
if (loginResult) {
return "redirect:/rm/dashboard";
} else {
model.addAttribute("error", "Invalid username or password");
return "login";
}
}
public String logout(HttpServletRequest request, HttpServletResponse response) {
userService.logout(request, response);
return "redirect:/rm/login";
}
public String dashboard(HttpServletRequest request, Model model) {
RmUser user = (RmUser) request.getSession().getAttribute("user");
if (user == null) {
user = userService.getUserFromRememberMeCookie(request);
}
if (user != null) {
model.addAttribute("user", user);
return "rm/dashboard";
} else {
return "redirect:/rm/login";
}
}
}
创建登录页面和仪表盘页面
在resources/templates/rm 目录下创建login.html和dashboard.html,分别用于登录页面和仪表盘页面的展示。
以下是login.html和dashboard.html的基本代码框架和描述:
login.html
html lang="zh-CN">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>用户登录title>
head>
body>
h1>用户登录h1>
form action="/rm/login" method="post">
label for="username">用户名:label>
input type="text" id="username" name="username" required>br>
label for="password">密码:label>
input type="password" id="password" name="password" required>br>
label for="rememberMe">记住我:label>
input type="checkbox" id="rememberMe" name="rememberMe">br>
input type="submit" value="登录">
form>
body>
html>
dashboard.html
html lang="zh-CN">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>用户仪表盘title>
head>
body>
h1>欢迎来到仪表盘h1>
div>
p>你好,span th:text="${user.username}">span>!p>
a href="/rm/logout">注销a>
div>
body>
html>
以上代码示例演示了一个简单的用户登录和"记住我"功能的实现,核心算法包括:
用户登录验证:在UserService中,通过查询数据库验证用户提供的用户名和密码是否匹配。
"记住我"功能:通过随机生成一个rememberToken,将其存储到用户表中,并将该rememberToken存储到Cookie中,以便用户下次访问时免登录。
用户登出:清除Session中的用户信息并删除"记住我"功能的Cookie。
自动登录:从Cookie中获取rememberToken,查询数据库获取用户信息,实现自动登录。
示例中完整代码,可以从 https://github.com/icoderoad/wxdemo.git 下载获取。



文章评论