feat: 增加信任的反代IP设置 close #636

This commit is contained in:
wushuo
2026-03-07 01:57:08 +08:00
parent 5b46977d59
commit ffcc580d1e
7 changed files with 48 additions and 5 deletions

View File

@@ -32,6 +32,7 @@ import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -304,7 +305,7 @@ public class ConfigController extends BaseController {
@Auth
@Operation(summary = "导入设置")
@PostMapping("/importConfig")
@PostMapping(value = "/importConfig", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<Void> importConfig(@RequestParam("file") MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();
String extName = FileUtil.extName(originalFilename);

View File

@@ -9,6 +9,7 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -22,7 +23,7 @@ import java.io.IOException;
public class UploadController extends BaseController {
@Auth
@Operation(summary = "上传文件")
@PostMapping("/upload")
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<Object> upload(@RequestParam("file") MultipartFile file) throws IOException {
HttpServletRequest request = Global.REQUEST.get();
String type = request.getParameter("type");

View File

@@ -731,4 +731,10 @@ public class Config implements Serializable {
*/
@Schema(description = "构建信息")
private String buildInfo;
@Schema(description = "启用 受信任的反向代理IP")
private Boolean reverseProxyTrustIpListEnabled;
@Schema(description = "受信任的反向代理IP")
private List<String> reverseProxyTrustIpList;
}

View File

@@ -10,6 +10,7 @@ import ani.rss.entity.Global;
import ani.rss.entity.Login;
import ani.rss.entity.Result;
import ani.rss.exception.ResultException;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
@@ -20,6 +21,7 @@ import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@@ -97,8 +99,30 @@ public class AuthUtil {
*/
public static String getIp() {
try {
Config config = ConfigUtil.CONFIG;
List<String> reverseProxyTrustIpList = config.getReverseProxyTrustIpList();
Boolean reverseProxyTrustIpListEnabled = config.getReverseProxyTrustIpListEnabled();
HttpServletRequest request = Global.REQUEST.get();
return request.getRemoteAddr();
String ip = request.getRemoteAddr();
if (!reverseProxyTrustIpListEnabled) {
// 未启用 受信任的反向代理IP
return ip;
}
if (!reverseProxyTrustIpList.contains(ip)) {
// 不在名单中, 受信任的反向代理IP
return ip;
}
// https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Reference/Headers/X-Forwarded-For
String forwardedFor = request.getHeader("X-Forwarded-For");
if (StrUtil.isNotBlank(forwardedFor)) {
// 获取第一个IP
return NetUtil.getMultistageReverseProxyIp(forwardedFor);
}
return ip;
} catch (Exception e) {
String message = ExceptionUtils.getMessage(e);
log.error(message, e);

View File

@@ -230,7 +230,9 @@ public class ConfigUtil {
.setScrape(false)
.setReplace(false)
.setMaxFileNameLength(0)
.setLimitLoginAttempts(true);
.setLimitLoginAttempts(true)
.setReverseProxyTrustIpList(List.of("127.0.0.1"))
.setReverseProxyTrustIpListEnabled(false);
}
/**

View File

@@ -50,6 +50,13 @@
</div>
</div>
</el-form-item>
<el-form-item label="信任的反代IP">
<div style="width: 100%;">
<el-checkbox label="启用" v-model="config.reverseProxyTrustIpListEnabled"/>
<br>
<el-input-tag v-model="config.reverseProxyTrustIpList"/>
</div>
</el-form-item>
<el-form-item label="Api Key">
<div class="flex login-api-key-container">
<el-input v-model:model-value="props.config.apiKey" readonly/>

View File

@@ -126,5 +126,7 @@ export let configData = {
"priorityKeywords": [],
"procrastinatingMasterOnly": true,
"limitLoginAttempts": true,
"buildInfo": ''
"buildInfo": '',
"reverseProxyTrustIpList": [],
"reverseProxyTrustIpListEnabled": false
}