feat(oss): 增加对象存储模块并支持多种存储策略
- 新增对象存储服务模块 `han-note-oss`,集成 Rustfs、阿里云 OSS 及腾讯云 Cos 存储 - 提供统一的 `FileStrategy` 接口及 `FileStrategyFactory` 工厂类,根据存储类型动态选择存储策略 - 实现阿里云 OSS、腾讯云 Cos 和 Rustfs 具体存储逻辑 - 增加文件上传接口 `FileController`,支持接收文件并返回访问路径 - 完成用户密码更新接口,使用`spring.security`对密码进行加密
This commit is contained in:
@@ -97,6 +97,11 @@
|
||||
<groupId>com.hanserwei</groupId>
|
||||
<artifactId>hanserwei-spring-boot-starter-biz-context</artifactId>
|
||||
</dependency>
|
||||
<!-- 密码加密 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.hanserwei.hannote.auth.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PasswordEncoderConfig {
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
// BCrypt 是一种安全且适合密码存储的哈希算法,它在进行哈希时会自动加入“盐”,增加密码的安全性。
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
||||
System.out.println(encoder.encode("qwe123"));
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,17 @@ package com.hanserwei.hannote.auth.controller;
|
||||
|
||||
import com.hanserwei.framework.biz.operationlog.aspect.ApiOperationLog;
|
||||
import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO;
|
||||
import com.hanserwei.hannote.auth.service.UserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
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;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
@@ -30,4 +34,10 @@ public class UserController {
|
||||
public Response<?> logout() {
|
||||
return userService.logout();
|
||||
}
|
||||
|
||||
@PostMapping("/password/update")
|
||||
@ApiOperationLog(description = "修改密码")
|
||||
public Response<?> updatePassword(@Validated @RequestBody UpdatePasswordReqVO updatePasswordReqVO) {
|
||||
return userService.updatePassword(updatePasswordReqVO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ public enum ResponseCodeEnum implements BaseExceptionInterface {
|
||||
// ----------- 业务异常状态码 -----------
|
||||
VERIFICATION_CODE_SEND_FREQUENTLY("AUTH-20000", "请求太频繁,请3分钟后再试"),
|
||||
VERIFICATION_CODE_ERROR("AUTH-20001", "验证码错误"),
|
||||
LOGIN_TYPE_ERROR("AUTH-20002", "登录类型错误"),
|
||||
USER_NOT_FOUND("AUTH-20003", "该用户不存在"),
|
||||
MAIL_OR_PASSWORD_ERROR("AUTH-20004", "邮箱号或密码错误"),
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.hanserwei.hannote.auth.model.vo.user;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class UpdatePasswordReqVO {
|
||||
|
||||
@NotBlank(message = "新密码不能为空")
|
||||
private String newPassword;
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.hanserwei.hannote.auth.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.auth.domain.dataobject.UserDO;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO;
|
||||
|
||||
public interface UserService extends IService<UserDO> {
|
||||
@@ -20,4 +21,11 @@ public interface UserService extends IService<UserDO> {
|
||||
* @return 响应结果
|
||||
*/
|
||||
Response<?> logout();
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param updatePasswordReqVO 请求参数
|
||||
* @return 响应结果
|
||||
*/
|
||||
Response<?> updatePassword(UpdatePasswordReqVO updatePasswordReqVO);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.hanserwei.hannote.auth.domain.mapper.UserDOMapper;
|
||||
import com.hanserwei.hannote.auth.domain.mapper.UserRoleDOMapper;
|
||||
import com.hanserwei.hannote.auth.enums.LoginTypeEnum;
|
||||
import com.hanserwei.hannote.auth.enums.ResponseCodeEnum;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UpdatePasswordReqVO;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO;
|
||||
import com.hanserwei.hannote.auth.service.UserService;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -30,6 +31,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@@ -50,6 +52,7 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
|
||||
private final RoleDOMapper roleDOMapper;
|
||||
@Resource(name = "authTaskExecutor")
|
||||
private ThreadPoolTaskExecutor authTaskExecutor;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public Response<String> loginAndRegister(UserLoginReqVO reqVO) {
|
||||
@@ -87,6 +90,19 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
|
||||
}
|
||||
break;
|
||||
case PASSWORD:
|
||||
String password = reqVO.getPassword();
|
||||
// 根据邮箱号查询
|
||||
UserDO userDO1 = this.getOne(new QueryWrapper<UserDO>().eq("email", email));
|
||||
if (Objects.isNull(userDO1)){
|
||||
throw new ApiException(ResponseCodeEnum.USER_NOT_FOUND);
|
||||
}
|
||||
// 拿到密文密码
|
||||
String encodePassword = userDO1.getPassword();
|
||||
boolean isPasswordCorrect = passwordEncoder.matches(password, encodePassword);
|
||||
if (!isPasswordCorrect) {
|
||||
throw new ApiException(ResponseCodeEnum.MAIL_OR_PASSWORD_ERROR);
|
||||
}
|
||||
userId = userDO1.getId();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -158,4 +174,23 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
|
||||
StpUtil.logout(userId);
|
||||
return Response.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response<?> updatePassword(UpdatePasswordReqVO updatePasswordReqVO) {
|
||||
// 新密码
|
||||
String newPassword = updatePasswordReqVO.getNewPassword();
|
||||
// 加密后的密码
|
||||
String encodePassword = passwordEncoder.encode(newPassword);
|
||||
// 获取用户ID
|
||||
Long userId = LoginUserContextHolder.getUserId();
|
||||
|
||||
UserDO userDO = UserDO.builder()
|
||||
.id(userId)
|
||||
.password(encodePassword)
|
||||
.updateTime(LocalDateTime.now())
|
||||
.build();
|
||||
// 更新用户密码
|
||||
this.updateById(userDO);
|
||||
return Response.success();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user