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

文章目录

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了
相关推荐
Chrikk1 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*1 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue1 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man1 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟1 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity2 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天2 小时前
java的threadlocal为何内存泄漏
java
caridle3 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^3 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋33 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx