3.4 用户登录、校验
This commit is contained in:
parent
3ff8188dd8
commit
b0cf0b54ab
@ -0,0 +1,16 @@
|
||||
package edu.whut.smilepicturebackend.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AuthCheck {
|
||||
|
||||
/**
|
||||
* 必须具有某个角色
|
||||
**/
|
||||
String mustRole() default "";
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package edu.whut.smilepicturebackend.constant;
|
||||
|
||||
/**
|
||||
* 用户常量
|
||||
*/
|
||||
public interface UserConstant {
|
||||
|
||||
/**
|
||||
* 用户登录态键
|
||||
*/
|
||||
String USER_LOGIN_STATE = "user_login";
|
||||
|
||||
// region 权限
|
||||
|
||||
/**
|
||||
* 默认角色
|
||||
*/
|
||||
String DEFAULT_ROLE = "user";
|
||||
|
||||
/**
|
||||
* 管理员角色
|
||||
*/
|
||||
String VIP_ROLE = "vip";
|
||||
|
||||
/**
|
||||
* 管理员角色
|
||||
*/
|
||||
String ADMIN_ROLE = "admin";
|
||||
|
||||
// endregion
|
||||
}
|
@ -4,13 +4,15 @@ import edu.whut.smilepicturebackend.common.BaseResponse;
|
||||
import edu.whut.smilepicturebackend.common.ResultUtils;
|
||||
import edu.whut.smilepicturebackend.exception.ErrorCode;
|
||||
import edu.whut.smilepicturebackend.exception.ThrowUtils;
|
||||
import edu.whut.smilepicturebackend.model.dto.UserLoginRequest;
|
||||
import edu.whut.smilepicturebackend.model.dto.UserRegisterRequest;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.vo.LoginUserVO;
|
||||
import edu.whut.smilepicturebackend.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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 org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
@RestController
|
||||
@ -31,4 +33,36 @@ public class UserController {
|
||||
long result = userService.userRegister(userAccount, userPassword, checkPassword);
|
||||
return ResultUtils.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*/
|
||||
//TODO:目前是存在session中,待改为token JWT
|
||||
@PostMapping("/login")
|
||||
public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
|
||||
ThrowUtils.throwIf(userLoginRequest == null, ErrorCode.PARAMS_ERROR);
|
||||
String userAccount = userLoginRequest.getUserAccount();
|
||||
String userPassword = userLoginRequest.getUserPassword();
|
||||
LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
|
||||
return ResultUtils.success(loginUserVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*/
|
||||
@GetMapping("/get/login")
|
||||
public BaseResponse<LoginUserVO> getLoginUser(HttpServletRequest request) {
|
||||
User loginUser = userService.getLoginUser(request);
|
||||
return ResultUtils.success(userService.getLoginUserVO(loginUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注销
|
||||
*/
|
||||
@PostMapping("/logout")
|
||||
public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
|
||||
ThrowUtils.throwIf(request == null, ErrorCode.PARAMS_ERROR);
|
||||
boolean result = userService.userLogout(request);
|
||||
return ResultUtils.success(result);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package edu.whut.smilepicturebackend.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户登录请求
|
||||
*/
|
||||
@Data
|
||||
public class UserLoginRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8735650154179439661L;
|
||||
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String userPassword;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package edu.whut.smilepicturebackend.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 已登录用户视图(脱敏) isDelete和password没返回
|
||||
*/
|
||||
@Data
|
||||
public class LoginUserVO implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String userAvatar;
|
||||
|
||||
/**
|
||||
* 用户简介
|
||||
*/
|
||||
private String userProfile;
|
||||
|
||||
/**
|
||||
* 用户角色:user/admin
|
||||
*/
|
||||
private String userRole;
|
||||
|
||||
/**
|
||||
* 编辑时间
|
||||
*/
|
||||
private Date editTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -2,6 +2,9 @@ package edu.whut.smilepicturebackend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.vo.LoginUserVO;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author 张三
|
||||
@ -25,6 +28,44 @@ public interface UserService extends IService<User> {
|
||||
* @return
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 获取加密后的密码
|
||||
*
|
||||
* @param userPassword
|
||||
* @return
|
||||
*/
|
||||
String getEncryptPassword(String userPassword);
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param userAccount 用户账户
|
||||
* @param userPassword 用户密码
|
||||
* @return 脱敏后的用户信息
|
||||
*/
|
||||
LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获得脱敏后的登录用户信息
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
LoginUserVO getLoginUserVO(User user);
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
User getLoginUser(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
boolean userLogout(HttpServletRequest request);
|
||||
}
|
||||
|
@ -1,23 +1,32 @@
|
||||
package edu.whut.smilepicturebackend.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import edu.whut.smilepicturebackend.constant.UserConstant;
|
||||
import edu.whut.smilepicturebackend.exception.BusinessException;
|
||||
import edu.whut.smilepicturebackend.exception.ErrorCode;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.enums.UserRoleEnum;
|
||||
import edu.whut.smilepicturebackend.model.vo.LoginUserVO;
|
||||
import edu.whut.smilepicturebackend.service.UserService;
|
||||
import edu.whut.smilepicturebackend.mapper.UserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* @author 张三
|
||||
* @description 针对表【user(用户)】的数据库操作Service实现
|
||||
* @createDate 2025-06-05 17:43:52
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
||||
implements UserService{
|
||||
@ -46,9 +55,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
|
||||
}
|
||||
// 2. 检查用户账号是否和数据库中已有的重复
|
||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("userAccount", userAccount);
|
||||
long count = this.baseMapper.selectCount(queryWrapper);
|
||||
LambdaQueryWrapper<User> lambda = Wrappers.lambdaQuery();
|
||||
lambda.eq(User::getUserAccount, userAccount);
|
||||
long count = this.baseMapper.selectCount(lambda);
|
||||
if (count > 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
|
||||
}
|
||||
@ -79,6 +88,87 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
||||
// final String SALT = "smile12306";
|
||||
// return DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {
|
||||
// 1. 校验
|
||||
if (StrUtil.hasBlank(userAccount, userPassword)) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
|
||||
}
|
||||
if (userAccount.length() < 4) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号错误");
|
||||
}
|
||||
if (userPassword.length() < 8) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码错误");
|
||||
}
|
||||
// 2. 对用户传递的密码进行加密
|
||||
String encryptPassword = getEncryptPassword(userPassword);
|
||||
// 3. 查询数据库中的用户是否存在
|
||||
LambdaQueryWrapper<User> lambda = new LambdaQueryWrapper<>();
|
||||
lambda
|
||||
.eq(User::getUserAccount, userAccount)
|
||||
.eq(User::getUserPassword, encryptPassword);
|
||||
User user = this.baseMapper.selectOne(lambda);
|
||||
// 不存在,抛异常
|
||||
if (user == null) {
|
||||
log.info("user login failed, userAccount cannot match userPassword");
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或者密码错误");
|
||||
}
|
||||
// 4. 保存用户的登录态
|
||||
request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user);
|
||||
return this.getLoginUserVO(user);
|
||||
|
||||
}
|
||||
/**
|
||||
* 获取脱敏类的用户信息
|
||||
*
|
||||
* @param user 用户
|
||||
* @return 脱敏后的用户信息
|
||||
*/
|
||||
@Override
|
||||
public LoginUserVO getLoginUserVO(User user) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
LoginUserVO loginUserVO = new LoginUserVO();
|
||||
BeanUtil.copyProperties(user, loginUserVO);
|
||||
return loginUserVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getLoginUser(HttpServletRequest request) {
|
||||
// 判断是否已经登录
|
||||
Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
|
||||
User currentUser = (User) userObj;
|
||||
if (currentUser == null || currentUser.getId() == null) {
|
||||
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
// 从数据库中查询(追求性能的话可以注释,直接返回上述结果)
|
||||
Long userId = currentUser.getId();
|
||||
currentUser = this.getById(userId);
|
||||
if (currentUser == null) {
|
||||
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
|
||||
}
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean userLogout(HttpServletRequest request) {
|
||||
// 判断是否已经登录
|
||||
Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
|
||||
if (userObj == null) {
|
||||
throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录");
|
||||
}
|
||||
// 移除登录态
|
||||
request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@ spring:
|
||||
password: 123456
|
||||
|
||||
mybatis-plus:
|
||||
type-aliases-package: edu.whut.smilepicturebackend.model.entity
|
||||
configuration:
|
||||
# MyBatis 配置
|
||||
map-underscore-to-camel-case: true #是否开启驼峰转换
|
||||
|
27
src/main/resources/mapper/UserMapper.xml
Normal file
27
src/main/resources/mapper/UserMapper.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="edu.whut.smilepicturebackend.mapper.UserMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="edu.whut.smilepicturebackend.model.entity.User">
|
||||
<id property="id" column="id" jdbcType="BIGINT"/>
|
||||
<result property="userAccount" column="user_account" jdbcType="VARCHAR"/>
|
||||
<result property="userPassword" column="user_password" jdbcType="VARCHAR"/>
|
||||
<result property="userName" column="user_name" jdbcType="VARCHAR"/>
|
||||
<result property="userAvatar" column="user_avatar" jdbcType="VARCHAR"/>
|
||||
<result property="userProfile" column="user_profile" jdbcType="VARCHAR"/>
|
||||
<result property="userRole" column="user_role" jdbcType="VARCHAR"/>
|
||||
<result property="editTime" column="edit_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,user_account,user_password,
|
||||
user_name,user_avatar,user_profile,
|
||||
user_role,edit_time,create_time,
|
||||
update_time,is_delete
|
||||
</sql>
|
||||
</mapper>
|
Loading…
x
Reference in New Issue
Block a user