登录密码加密,反向解密
This commit is contained in:
88
src/main/java/com/rj/common/PasswordUtil.java
Normal file
88
src/main/java/com/rj/common/PasswordUtil.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package com.rj.common;
|
||||
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
/**
|
||||
* 密码工具类
|
||||
*
|
||||
* @author 系统生成
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
public class PasswordUtil {
|
||||
|
||||
/**
|
||||
* 默认盐值
|
||||
*/
|
||||
private static final String DEFAULT_SALT = "rj_system_2025";
|
||||
|
||||
/**
|
||||
* MD5加密密码
|
||||
*
|
||||
* @param password 原始密码
|
||||
* @return 加密后的密码
|
||||
*/
|
||||
public static String encryptPassword(String password) {
|
||||
return DigestUtils.md5DigestAsHex(password.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密密码(带盐值)
|
||||
*
|
||||
* @param password 原始密码
|
||||
* @param salt 盐值
|
||||
* @return 加密后的密码
|
||||
*/
|
||||
public static String encryptPassword(String password, String salt) {
|
||||
String saltedPassword = password + salt;
|
||||
return DigestUtils.md5DigestAsHex(saltedPassword.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认盐值加密密码
|
||||
*
|
||||
* @param password 原始密码
|
||||
* @return 加密后的密码
|
||||
*/
|
||||
public static String encryptPasswordWithDefaultSalt(String password) {
|
||||
return encryptPassword(password, DEFAULT_SALT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证密码
|
||||
*
|
||||
* @param inputPassword 输入的密码
|
||||
* @param encryptedPassword 数据库中存储的加密密码
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public static boolean verifyPassword(String inputPassword, String encryptedPassword) {
|
||||
String inputEncrypted = encryptPassword(inputPassword,DEFAULT_SALT);
|
||||
return inputEncrypted.equals(encryptedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证密码(带盐值)
|
||||
*
|
||||
* @param inputPassword 输入的密码
|
||||
* @param encryptedPassword 数据库中存储的加密密码
|
||||
* @param salt 盐值
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public static boolean verifyPassword(String inputPassword, String encryptedPassword, String salt) {
|
||||
String inputEncrypted = encryptPassword(inputPassword, DEFAULT_SALT);
|
||||
return inputEncrypted.equals(encryptedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认盐值验证密码
|
||||
*
|
||||
* @param inputPassword 输入的密码
|
||||
* @param encryptedPassword 数据库中存储的加密密码
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public static boolean verifyPasswordWithDefaultSalt(String inputPassword, String encryptedPassword) {
|
||||
return verifyPassword(inputPassword, encryptedPassword, DEFAULT_SALT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
171
src/main/java/com/rj/controller/sys/AuthController.java
Normal file
171
src/main/java/com/rj/controller/sys/AuthController.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package com.rj.controller.sys;
|
||||
|
||||
import com.rj.common.Result;
|
||||
import com.rj.entity.sys.User;
|
||||
import com.rj.pojo.sys.LoginRequest;
|
||||
import com.rj.pojo.sys.LoginResponse;
|
||||
import com.rj.service.sys.IUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 认证控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 系统生成
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/sys/auth")
|
||||
@Tag(name = "认证管理", description = "用户认证相关接口")
|
||||
@Slf4j
|
||||
public class AuthController {
|
||||
|
||||
@Autowired
|
||||
private IUserService userService;
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "用户登录", description = "根据用户名和密码进行登录验证")
|
||||
public ResponseEntity<Map<String, Object>> login(
|
||||
@Parameter(description = "登录信息", required = true)
|
||||
@Valid @RequestBody LoginRequest loginRequest) {
|
||||
log.info("用户登录:{}", loginRequest);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
LoginResponse loginResponse = userService.login(loginRequest);
|
||||
result.put("success", true);
|
||||
result.put("message", "登录成功");
|
||||
result.put("data", loginResponse);
|
||||
return ResponseEntity.ok(result);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", "登录失败:" + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "通过token获取用户信息")
|
||||
@GetMapping(value = "/getUserInfoByToken")
|
||||
public ResponseEntity getUserInfoByToken(String token){
|
||||
log.info("通过token获取用户信息:{}", token);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
// 用户信息/角色信息
|
||||
User user = userService.getUserInfoByToken(token);
|
||||
user.setPassword(null);
|
||||
user.setOriginalPassword(null);
|
||||
result.put("success", true);
|
||||
result.put("data", user);
|
||||
result.put("message", "token验证成功");
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
*/
|
||||
@PostMapping("/logout")
|
||||
@Operation(summary = "用户登出", description = "清除用户token,实现登出功能")
|
||||
public ResponseEntity<Map<String, Object>> logout(
|
||||
@Parameter(description = "用户ID", required = true)
|
||||
@RequestParam Integer userId) {
|
||||
log.info("用户登出:{}", userId);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
User user = userService.getById(userId);
|
||||
if (user != null) {
|
||||
// 清除token
|
||||
user.setToken(null);
|
||||
userService.updateById(user);
|
||||
result.put("success", true);
|
||||
result.put("message", "登出成功");
|
||||
return ResponseEntity.ok(result);
|
||||
} else {
|
||||
result.put("success", false);
|
||||
result.put("message", "用户不存在");
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", "登出失败:" + e.getMessage());
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
*/
|
||||
@GetMapping("/verify")
|
||||
@Operation(summary = "验证token", description = "验证用户token是否有效")
|
||||
public ResponseEntity<Map<String, Object>> verifyToken(
|
||||
@Parameter(description = "token", required = true)
|
||||
@RequestParam String token) {
|
||||
log.info("验证token:{}", token);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
// 根据token查询用户
|
||||
User user = userService.getUserByToken(token);
|
||||
if (user != null) {
|
||||
result.put("success", true);
|
||||
result.put("message", "token有效");
|
||||
result.put("data", user);
|
||||
return ResponseEntity.ok(result);
|
||||
} else {
|
||||
result.put("success", false);
|
||||
result.put("message", "token无效或已过期");
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", "验证失败:" + e.getMessage());
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
*/
|
||||
@GetMapping("/current")
|
||||
@Operation(summary = "获取当前用户信息", description = "根据token获取当前登录用户信息")
|
||||
public ResponseEntity<Map<String, Object>> getCurrentUser(
|
||||
@Parameter(description = "token", required = true)
|
||||
@RequestParam String token) {
|
||||
log.info("获取当前用户信息:{}", token);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
User user = userService.getUserByToken(token);
|
||||
if (user != null) {
|
||||
// 不返回密码等敏感信息
|
||||
user.setPassword(null);
|
||||
result.put("success", true);
|
||||
result.put("message", "获取成功");
|
||||
result.put("data", user);
|
||||
return ResponseEntity.ok(result);
|
||||
} else {
|
||||
result.put("success", false);
|
||||
result.put("message", "用户未登录或token已过期");
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", "获取用户信息失败:" + e.getMessage());
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
26
src/main/java/com/rj/pojo/sys/LoginRequest.java
Normal file
26
src/main/java/com/rj/pojo/sys/LoginRequest.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.rj.pojo.sys;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 登录请求DTO
|
||||
*
|
||||
* @author 系统生成
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "登录请求")
|
||||
public class LoginRequest {
|
||||
|
||||
@Schema(description = "用户名", required = true, example = "admin")
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "密码", required = true, example = "123456")
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
}
|
||||
37
src/main/java/com/rj/pojo/sys/LoginResponse.java
Normal file
37
src/main/java/com/rj/pojo/sys/LoginResponse.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.rj.pojo.sys;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 登录响应DTO
|
||||
*
|
||||
* @author 系统生成
|
||||
* @since 2025-08-07
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "登录响应")
|
||||
public class LoginResponse {
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "用户名")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "访问令牌")
|
||||
private String token;
|
||||
|
||||
@Schema(description = "登录时间")
|
||||
private String loginTime;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
25
src/main/resources/sql/test_user_data.sql
Normal file
25
src/main/resources/sql/test_user_data.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- 测试用户数据
|
||||
-- 密码都是 123456 的MD5加密值
|
||||
|
||||
-- 插入测试用户
|
||||
INSERT INTO `user` (`user_name`, `email`, `password`, `avatar`) VALUES
|
||||
('admin', 'admin@example.com', 'e10adc3949ba59abbe56e057f20f883e', '/avatar/admin.jpg'),
|
||||
('user1', 'user1@example.com', 'e10adc3949ba59abbe56e057f20f883e', '/avatar/user1.jpg'),
|
||||
('user2', 'user2@example.com', 'e10adc3949ba59abbe56e057f20f883e', '/avatar/user2.jpg'),
|
||||
('test', 'test@example.com', 'e10adc3949ba59abbe56e057f20f883e', '/avatar/test.jpg');
|
||||
|
||||
-- 插入测试角色
|
||||
INSERT INTO `role` (`role_name`) VALUES
|
||||
('管理员'),
|
||||
('普通用户'),
|
||||
('访客');
|
||||
|
||||
-- 插入用户角色关联
|
||||
INSERT INTO `user_role` (`user_id`, `role_id`) VALUES
|
||||
(1, 1), -- admin -> 管理员
|
||||
(2, 2), -- user1 -> 普通用户
|
||||
(3, 2), -- user2 -> 普通用户
|
||||
(4, 3); -- test -> 访客
|
||||
|
||||
|
||||
|
||||
15
src/main/resources/sql/update_user_table.sql
Normal file
15
src/main/resources/sql/update_user_table.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- 更新用户表结构,添加原始密码字段
|
||||
-- 执行时间:2025-08-07
|
||||
|
||||
-- 为user表添加original_password字段
|
||||
ALTER TABLE `user`
|
||||
ADD COLUMN `original_password` varchar(255) DEFAULT NULL COMMENT '原始密码'
|
||||
AFTER `password`;
|
||||
|
||||
-- 更新现有用户的原始密码字段(如果密码是123456的MD5值,则设置原始密码为123456)
|
||||
UPDATE `user`
|
||||
SET `original_password` = '123456'
|
||||
WHERE `password` = 'e10adc3949ba59abbe56e057f20f883e';
|
||||
|
||||
-- 为original_password字段添加索引(可选)
|
||||
-- ALTER TABLE `user` ADD INDEX `idx_original_password` (`original_password`);
|
||||
Reference in New Issue
Block a user