package com.emergencyrepair.auth;
|
|
import com.emergencyrepair.common.Result;
|
import com.emergencyrepair.system.entity.SysLoginLog;
|
import com.emergencyrepair.system.mapper.SysLoginLogMapper;
|
import com.emergencyrepair.system.service.SystemService;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.dao.DataAccessException;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.util.StringUtils;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestHeader;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.time.LocalDateTime;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@RestController
|
@RequestMapping("/api/auth")
|
@RequiredArgsConstructor
|
public class AuthController {
|
private final JdbcTemplate jdbcTemplate;
|
private final SysLoginLogMapper loginLogMapper;
|
private final SystemService systemService;
|
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
|
@PostMapping("/login")
|
public Result<Map<String, Object>> login(@RequestBody Map<String, String> body, HttpServletRequest request) {
|
String username = body == null || body.get("username") == null ? "" : body.get("username").trim();
|
String password = body == null || body.get("password") == null ? "" : body.get("password");
|
Map<String, Object> user = findUser(username);
|
boolean success = false;
|
String message = "用户名或密码错误";
|
if (user != null) {
|
if (isDisabled(user)) {
|
message = "账号已停用";
|
} else if (matches(password, stringValue(user.get("password")))) {
|
success = true;
|
} else if ("admin".equals(username) && ("admin".equals(password) || "admin123".equals(password))) {
|
// Keep the original demo credential working for the built-in administrator.
|
success = true;
|
}
|
}
|
recordLogin(username, user, request, success, success ? "登录成功" : message);
|
if (!success) {
|
return Result.error(message);
|
}
|
Map<String, Object> data = new LinkedHashMap<>();
|
data.put("token", "demo-" + username + "-token");
|
data.put("username", username);
|
data.put("realName", StringUtils.hasText(stringValue(user.get("nickName")))
|
? stringValue(user.get("nickName")) : username);
|
data.put("deptName", stringValue(user.get("deptName")));
|
data.put("roles", systemService.roleCodes(username));
|
data.put("permissions", systemService.permissionCodes(username));
|
return Result.ok(data);
|
}
|
|
@GetMapping("/me")
|
public Result<Map<String, Object>> me(@RequestHeader(value = "X-Username", required = false) String headerUser,
|
@RequestHeader(value = "Authorization", required = false) String authorization) {
|
String username = currentUsername(headerUser, authorization);
|
Map<String, Object> user = findUser(username);
|
if (user == null) {
|
return Result.error("登录状态已失效");
|
}
|
Map<String, Object> data = new LinkedHashMap<>();
|
data.put("username", username);
|
data.put("realName", StringUtils.hasText(stringValue(user.get("nickName")))
|
? stringValue(user.get("nickName")) : username);
|
data.put("deptName", stringValue(user.get("deptName")));
|
data.put("roles", systemService.roleCodes(username));
|
data.put("permissions", systemService.permissionCodes(username));
|
return Result.ok(data);
|
}
|
|
private Map<String, Object> findUser(String username) {
|
if (!StringUtils.hasText(username)) {
|
return null;
|
}
|
try {
|
List<Map<String, Object>> rows = jdbcTemplate.query(
|
"SELECT u.USER_ID, u.USER_NAME, u.NICK_NAME, u.PASSWORD, u.STATUS, d.DEPT_NAME " +
|
"FROM LX.SYS_USER u LEFT JOIN LX.SYS_DEPT d ON d.DEPT_ID = u.DEPT_ID " +
|
"WHERE u.USER_NAME = ? AND (u.DEL_FLAG = '0' OR u.DEL_FLAG IS NULL)",
|
new Object[]{username},
|
(rs, rowNum) -> {
|
Map<String, Object> row = new LinkedHashMap<>();
|
row.put("userId", rs.getLong("USER_ID"));
|
row.put("userName", rs.getString("USER_NAME"));
|
row.put("nickName", rs.getString("NICK_NAME"));
|
row.put("password", rs.getString("PASSWORD"));
|
row.put("status", rs.getString("STATUS"));
|
row.put("deptName", rs.getString("DEPT_NAME"));
|
return row;
|
});
|
return rows.isEmpty() ? null : rows.get(0);
|
} catch (DataAccessException ex) {
|
return null;
|
}
|
}
|
|
private boolean matches(String rawPassword, String encodedPassword) {
|
if (!StringUtils.hasText(rawPassword) || !StringUtils.hasText(encodedPassword)) {
|
return false;
|
}
|
try {
|
return passwordEncoder.matches(rawPassword, encodedPassword.trim());
|
} catch (Exception ex) {
|
return false;
|
}
|
}
|
|
private boolean isDisabled(Map<String, Object> user) {
|
return "1".equals(stringValue(user.get("status")));
|
}
|
|
private String stringValue(Object value) {
|
return value == null ? "" : String.valueOf(value).trim();
|
}
|
|
private String currentUsername(String headerUser, String authorization) {
|
if (StringUtils.hasText(headerUser)) {
|
return headerUser.trim();
|
}
|
if (!StringUtils.hasText(authorization)) {
|
return "";
|
}
|
String token = authorization.trim();
|
if (token.startsWith("Bearer ")) {
|
token = token.substring(7).trim();
|
}
|
if (token.startsWith("demo-") && token.endsWith("-token")) {
|
return token.substring(5, token.length() - 6);
|
}
|
return token;
|
}
|
|
private void recordLogin(String username, Map<String, Object> user, HttpServletRequest request,
|
boolean success, String message) {
|
try {
|
SysLoginLog log = new SysLoginLog();
|
log.setUserId(user == null ? null : (Long) user.get("userId"));
|
log.setUserName(username);
|
log.setNickName(user == null ? null : stringValue(user.get("nickName")));
|
log.setDeptName(user == null ? "" : stringValue(user.get("deptName")));
|
log.setLoginIp(clientIp(request));
|
log.setStatus(success ? "SUCCESS" : "FAIL");
|
log.setMessage(message);
|
log.setLoginTime(LocalDateTime.now());
|
loginLogMapper.insert(log);
|
} catch (Exception ignored) {
|
// Login must not fail because the audit table is unavailable.
|
}
|
}
|
|
private String clientIp(HttpServletRequest request) {
|
if (request == null) {
|
return "";
|
}
|
String forwarded = request.getHeader("X-Forwarded-For");
|
if (StringUtils.hasText(forwarded)) {
|
return forwarded.split(",")[0].trim();
|
}
|
return request.getRemoteAddr();
|
}
|
}
|