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

文章目录

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了
相关推荐
葫芦和十三18 分钟前
图解 MongoDB 22|读写关注:持久性与一致性的档位选择
后端·mongodb·agent
葫芦和十三7 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp7 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑8 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯9 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan11 小时前
多Agent之间的区别
后端
青石路13 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充13 小时前
1.面向对象设计思想
后端
IT_陈寒13 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro14 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端