用户中心项目(登录 + 用户管理功能后端)

文章目录

1.登录功能-后端

1.思路分析
2.完成对用户名和密码的校验
1.com/sun/usercenter/service/UserService.java 添加方法
java 复制代码
    public Long userRegister(String userAccount, String userPassword, String checkPassword);

    /**
     * 用户登录接口
     * @param userAccount 账号
     * @param userPassword 密码
     * @return 成功返回脱敏后的User对象,失败返回null
     */
    public User doLogin(String userAccount, String userPassword);
2.com/sun/usercenter/service/impl/UserServiceImpl.java 添加方法
java 复制代码
    @Override
    public User doLogin(String userAccount, String userPassword) {
        // 1 检验用户名和密码是否合法,如果不合法就没必要去数据库查询
        // 验证非空
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            return null;
        }
        // 账户4到16位,不能包含特殊字符
        if (!userAccount.matches("^[a-zA-Z0-9]{4,16}$")) {
            return null;
        }
        // 密码不小于8位
        if (userPassword.length() < 8) {
            return null;
        }

        // 2 密码加密进行查询
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());

        // 编写查询条件
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("userPassword", encryptPassword);
        userQueryWrapper.eq("userAccount", userAccount);
        // 执行查询
        User user = userMapper.selectOne(userQueryWrapper);
        // 判断用户是否存在
        if (user == null) {
            // 输出日志
            log.info("user login faild, userAccount can not match password");
            return null;
        }

        // 3 记录用户的登录态


        return user;
    }
3.com/sun/usercenter/service/impl/UserServiceImpl.java 新增属性
3.记录用户的登录态并配置MyBatisPlus的逻辑删除
1.com/sun/usercenter/service/UserService.java 修改doLogin,增加参数 request
java 复制代码
    /**
     * 用户登录接口
     * @param userAccount 账号
     * @param userPassword 密码
     * @return 成功返回脱敏后的User对象,失败返回null
     */
    public User doLogin(String userAccount, String userPassword, HttpServletRequest request);
2.com/sun/usercenter/service/impl/UserServiceImpl.java 新增属性
3.com/sun/usercenter/service/impl/UserServiceImpl.java 添加代码
doLogin 方法添加代码,记录用户登录态
java 复制代码
        // 3 如果登录成功,记录用户的登录态

        // 首先进行脱敏
        User cleanUser = new User();
        cleanUser.setId(user.getId());
        cleanUser.setUsername(user.getUsername());
        cleanUser.setUserAccount(user.getUserAccount());
        cleanUser.setAvatarUrl(user.getAvatarUrl());
        cleanUser.setGender(user.getGender());
        cleanUser.setPhone(user.getPhone());
        cleanUser.setEmail(user.getEmail());
        cleanUser.setUserStatus(user.getUserStatus());
        cleanUser.setCreateTime(user.getCreateTime());

        HttpSession session = request.getSession();
        // 然后将脱敏后的用户信息放入session中
        session.setAttribute(USER_LOGIN_SAVE, cleanUser);

        return cleanUser;
4.配置MyBatisPlus的逻辑删除
1.application.yml 配置
yaml 复制代码
global-config:
  db-config:
    logic-delete-field: isDelete # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
    logic-delete-value: 1 # 逻辑已删除值(默认为 1)
    logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
2.实体类添加注解

2.接口开发及测试

1.com/sun/usercenter/controller/UserController.java 注册和登录接口
java 复制代码
package com.sun.usercenter.controller;

import com.sun.usercenter.model.domain.User;
import com.sun.usercenter.model.request.UserLoginRequest;
import com.sun.usercenter.model.request.UserRegisterRequest;
import com.sun.usercenter.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/3/21 13:04
 * @Version 1.0
 */
@RestController // 作为一个Controller注入容器,并将返回结果转换为json
@RequestMapping("/user") // restful风格的请求
public class UserController {
    @Resource
    private UserService userService; // 注入针对Service接口的bean对象,可以调用接口的方法

    @PostMapping("/register")
    public Long userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
        // 首先判断数据是否成功封装
        if (userRegisterRequest == null) {
            return null;
        }

        // 对封装的数据进行校验,如果有一个是空直接返回null
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            return null;
        }

        // 调用Service层的注册方法,如果成功注册,则返回注册成功的用户id, 否则返回-1
        return userService.userRegister(userAccount, userPassword, checkPassword);
    }

    @PostMapping("/login")
    public User userRegister(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        // 首先判断数据是否成功封装
        if (userLoginRequest == null) {
            return null;
        }

        // 对封装的数据进行校验,如果有一个是空直接返回null
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            return null;
        }

        return userService.doLogin(userAccount, userPassword, request);
    }

}
2.封装登录和注册请求信息的对象
1.文件目录
2.com/sun/usercenter/model/request/UserLoginRequest.java 用户登录请求体
java 复制代码
package com.sun.usercenter.model.request;

import lombok.Data;

/**
 * Description: 用户登录请求体
 *
 * @Author sun
 * @Create 2024/3/21 13:39
 * @Version 1.0
 */
@Data
public class UserLoginRequest {
    private String userAccount;
    private String userPassword;
}
3.com/sun/usercenter/model/request/UserRegisterRequest.java 用户注册请求体
java 复制代码
package com.sun.usercenter.model.request;


import lombok.Data;

/**
 * Description: 用户注册请求体
 *
 * @Author sun
 * @Create 2024/3/21 13:26
 * @Version 1.0
 */
@Data
public class UserRegisterRequest {
    private String userAccount;
    private String userPassword;
    private String checkPassword;
}
3.单元测试
1.用户注册接口测试
1.debug模式启动IDEA
2.postman测试
2.用户登录接口测试
1.com/sun/usercenter/service/impl/UserServiceImpl.java的doLogin最后下断点
2.postman测试
3.查看session是否有用户登录状态的信息
4.放行,查看postman的返回结果
3.逻辑删除测试
1.在数据库中把刚才进行登录的用户id改成1
2.重新登录一下

3.用户管理接口

1.com/sun/usercenter/controller/UserController.java 添加方法
java 复制代码
    /**
     * 根据用户名进行模糊查询
     *
     * @param username
     * @return 成功返回信息,失败返回null
     */
    @GetMapping("/search")
    public List<User> searchUsers(String username) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(username)) {
            userQueryWrapper.like("username", username);
        }
        return userService.list(userQueryWrapper);
    }

    /**
     * 根据id进行逻辑删除(只要配置了MyBatisPlus的逻辑删除即可进行自动逻辑删除)
     *
     * @param id
     * @return 成功返回true,失败返回false
     */
    @PostMapping("/delete")
    public boolean deleteUser(@RequestBody Long id) {
        if (id <= 0) {
            return false;
        }
        return userService.removeById(id); // 这里会自动逻辑删除
    }
2.user表新增字段role表示用户权限
1.新增字段role
2.com/sun/usercenter/model/domain/User.java 实体类新增权限字段
3.Mapper.xml不用修改,因为这个字段本来就与表的字段对应
4.com/sun/usercenter/service/impl/UserServiceImpl.java 用户脱敏里面把role字段加进去
3.com/sun/usercenter/contant/UserConstant.java 存放用户常量的接口
java 复制代码
package com.sun.usercenter.contant;

/**
 * Description: 用户常量
 *
 * @Author sun
 * @Create 2024/3/21 15:14
 * @Version 1.0
 */
public interface UserConstant {

    /*
    用户登录状态
     */
    String USER_LOGIN_SAVE = "userLoginState";

    // 用户权限

    /*
    默认权限
     */
    Integer DEFAULT_ROLE = 0;

    /*
    管理员权限
     */
    Integer ADMIN_ROLE = 1;
}
4.com/sun/usercenter/controller/UserController.java 对两个接口进行权限验证
1.添加方法 isAdmin 判断是否为管理员
java 复制代码
    /**
     * 判断是否是管理员
     * @param request
     * @return 布尔
     */
    public boolean isAdmin(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(USER_LOGIN_SAVE);
        return user != null && user.getRole() == ADMIN_ROLE;
    }
2.修改两个接口的方法
java 复制代码
    /**
     * 根据用户名进行模糊查询
     *
     * @param username
     * @return 成功返回信息,失败返回null
     */
    @GetMapping("/search")
    public List<User> searchUsers(String username, HttpServletRequest request) {
        // 仅管理员可查询
        if (!isAdmin(request)) {
            return new ArrayList<>();
        }

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(username)) {
            userQueryWrapper.like("username", username);
        }
        return userService.list(userQueryWrapper);
    }

    /**
     * 根据id进行逻辑删除(只要配置了MyBatisPlus的逻辑删除即可进行自动逻辑删除)
     *
     * @param id
     * @return 成功返回true,失败返回false
     */
    @PostMapping("/delete")
    public boolean deleteUser(long id, HttpServletRequest request) {
        // 仅管理员可删除
        if (!isAdmin(request)) {
            return false;
        }

        if (id <= 0) {
            return false;
        }
        return userService.removeById(id); // 这里会自动逻辑删除
    }
5.application.yml 设置session超时时间
6.单元测试
1.测试 searchUsers接口
1.登录
2.表中增加两条测试记录
3.进行查询,成功查询!
2.测试deleteUser接口
1.删除id为1的用户
2.查看数据库,成功进行逻辑删除
3.解决 searchUsers接口返回的用户信息没有脱敏的问题
1.com/sun/usercenter/service/UserService.java 添加方法
java 复制代码
    /**
     * 进行用户信息脱敏
     * @param user
     * @return
     */
    User getCleanUser(User user);
2.com/sun/usercenter/service/impl/UserServiceImpl.java 实现方法并修改逻辑
java 复制代码
    /**
     * 对得到的user对象,进行用户信息脱敏
     * @param user
     * @return
     */
    @Override
    public User getCleanUser(User user) {
        User cleanUser = new User();
        cleanUser.setId(user.getId());
        cleanUser.setUsername(user.getUsername());
        cleanUser.setUserAccount(user.getUserAccount());
        cleanUser.setAvatarUrl(user.getAvatarUrl());
        cleanUser.setGender(user.getGender());
        cleanUser.setPhone(user.getPhone());
        cleanUser.setEmail(user.getEmail());
        cleanUser.setUserStatus(user.getUserStatus());
        cleanUser.setCreateTime(user.getCreateTime());
        cleanUser.setRole(user.getRole());
        return cleanUser;
    }
3.com/sun/usercenter/controller/UserController.java 修改searchUsers方法对查询到的用户列表进行脱敏
java 复制代码
/**
 * 根据用户名进行模糊查询
 *
 * @param username
 * @return 成功返回信息,失败返回null
 */
@GetMapping("/search")
public List<User> searchUsers(String username, HttpServletRequest request) {
    // 仅管理员可查询
    if (!isAdmin(request)) {
        return new ArrayList<>();
    }

    QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
    if (StringUtils.isNotBlank(username)) {
        userQueryWrapper.like("username", username);
    }
    List<User> userList = userService.list(userQueryWrapper);

    // 将查询到的用户数据进行脱敏

    // 这里的逻辑就是把查询到User对象列表使用user来遍历然后对每个user对象进行脱敏最后组合成一个新的list
    return userList.stream().map(user -> {
       return userService.getCleanUser(user);
    }).collect(Collectors.toList());
}
4.再次测试,敏感信息变成null了
相关推荐
indexsunny几秒前
互联网大厂Java求职面试实战:Spring Boot微服务与Kafka消息队列解析
java·spring boot·微服务·面试·kafka·jpa
invicinble几秒前
关于spring的全量认识
java·spring
齐 飞1 分钟前
JDK8中stream中常用方法
java
moxiaoran57532 分钟前
Go语言并发处理
开发语言·后端·golang
小旭95273 分钟前
【Java 基础】泛型<T>
java·开发语言·intellij-idea
她说..4 分钟前
FIND_IN_SET()方法
xml·java·spring boot
Tony Bai5 分钟前
AI 时代,Go 语言会“失宠”还是“封神”?—— GopherCon 2025 圆桌深度复盘
开发语言·人工智能·后端·golang
花间相见7 分钟前
【JAVA开发】—— Maven核心用法与实战指南
java·python·maven
爱吃的强哥7 分钟前
Springboot 使用 SSE推送消息到客户端(Electron)
java·spring boot·electron
Elias不吃糖8 分钟前
Java Stream 流(Stream API)详细讲解
java·stream·