feat(token): 将token迁移至请求体并兼容旧版客户端

- C++客户端在请求payload中添加token字段
- .NET客户端在请求payload中添加token字段
- Rust客户端在请求payload中添加token字段
- SpringBoot2客户端移除buildTokenParameter调用,改为将token放入请求体
- SpringBoot3客户端移除buildTokenParameter调用,改为将token放入请求体
- SpringBoot2/3客户端新增getToken方法供内部调用
- 服务端增加兼容逻辑,优先从请求体获取token,为空时回退至URL query参数
This commit is contained in:
2026-09-13 21:07:56 +08:00
parent 70cb3e301e
commit af3cf2f6e6
8 changed files with 32 additions and 5 deletions
+1
View File
@@ -200,6 +200,7 @@ bool Client::fetch_changed() {
payload["version"] = config_.version; payload["version"] = config_.version;
payload["lastTime"] = last_time_; payload["lastTime"] = last_time_;
payload["ignoreGlobal"] = config_.ignore_global; payload["ignoreGlobal"] = config_.ignore_global;
payload["token"] = config_.token;
std::string resp = http_post(url, payload.dump()); std::string resp = http_post(url, payload.dump());
if (resp.empty()) { if (resp.empty()) {
+2 -1
View File
@@ -136,7 +136,8 @@ public class Client
env = _config.Env, env = _config.Env,
version = _config.Version, version = _config.Version,
lastTime = _lastTime, lastTime = _lastTime,
ignoreGlobal = _config.IgnoreGlobal ignoreGlobal = _config.IgnoreGlobal,
token = _config.Token
}; };
var content = new StringContent(JsonConvert.SerializeObject(payload), System.Text.Encoding.UTF8, "application/json"); var content = new StringContent(JsonConvert.SerializeObject(payload), System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(url, content); var response = await _httpClient.PostAsync(url, content);
+1
View File
@@ -238,6 +238,7 @@ impl Client {
"version": self.config.version, "version": self.config.version,
"lastTime": *self.last_time.lock().unwrap(), "lastTime": *self.last_time.lock().unwrap(),
"ignoreGlobal": self.config.ignore_global, "ignoreGlobal": self.config.ignore_global,
"token": self.config.token,
}); });
let resp = self.http_post(&url, &payload.to_string())?; let resp = self.http_post(&url, &payload.to_string())?;
@@ -487,6 +487,10 @@ public class ConfigcenterContext {
} }
} }
public String getToken() {
return token;
}
public String buildTokenParameter(String url) { public String buildTokenParameter(String url) {
if (token == null || token.isEmpty()) { if (token == null || token.isEmpty()) {
return url; return url;
@@ -48,12 +48,15 @@ public class InternalConfigChangeListener {
params.put("ignoreGlobal", String.valueOf(context.isIgnoreGlobal())); params.put("ignoreGlobal", String.valueOf(context.isIgnoreGlobal()));
} }
params.put("lastTime", Long.parseLong(ConfigcenterContext.getProperty(LATEST_FETCH_TIMESTAMP, String.valueOf(System.currentTimeMillis())))); params.put("lastTime", Long.parseLong(ConfigcenterContext.getProperty(LATEST_FETCH_TIMESTAMP, String.valueOf(System.currentTimeMillis()))));
if (context.getToken() != null && !context.getToken().isEmpty()) {
params.put("token", context.getToken());
}
hbScheduledExecutor.scheduleAtFixedRate(new Runnable() { hbScheduledExecutor.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
String safeUrl = ConfigcenterContext.getInstance().buildTokenParameter(url); String safeUrl = url;
String response = ConfigcenterContext.httpPostJson(safeUrl, JSON.toJSONString(params)); String response = ConfigcenterContext.httpPostJson(safeUrl, JSON.toJSONString(params));
if (response != null) { if (response != null) {
Map<String, Object> map = JSON.parseObject(response, Map.class); Map<String, Object> map = JSON.parseObject(response, Map.class);
@@ -645,6 +645,10 @@ public class ConfigcenterContext {
} }
} }
public String getToken() {
return token;
}
public String buildTokenParameter(String url) { public String buildTokenParameter(String url) {
if (StringUtils.isBlank(token)) { if (StringUtils.isBlank(token)) {
return url; return url;
@@ -82,13 +82,16 @@ public class InternalConfigChangeListener {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void poll(ConfigcenterContext context, String[] baseUrls) { private void poll(ConfigcenterContext context, String[] baseUrls) {
for (String baseUrl : baseUrls) { for (String baseUrl : baseUrls) {
String url = context.buildTokenParameter(baseUrl + "/api/fetchChangedConfigs"); String url = baseUrl + "/api/fetchChangedConfigs";
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("version", context.getVersion()); params.put("version", context.getVersion());
params.put("appName", context.getApp()); params.put("appName", context.getApp());
params.put("env", context.getEnv()); params.put("env", context.getEnv());
params.put("ignoreGlobal", context.isIgnoreGlobal()); params.put("ignoreGlobal", context.isIgnoreGlobal());
params.put("lastTime", lastTime); params.put("lastTime", lastTime);
if (context.getToken() != null && !context.getToken().isEmpty()) {
params.put("token", context.getToken());
}
String response; String response;
try { try {
+12 -2
View File
@@ -86,7 +86,12 @@ func (h *ConfigApiHandler) FetchAllConfigs(c *gin.Context) {
} }
// validate token if app has token configured // validate token if app has token configured
if app.Token != "" && app.Token != req.Token { // 兼容旧版客户端把 token 放在 URL query 中的行为
token := req.Token
if token == "" {
token = c.Query("token")
}
if app.Token != "" && app.Token != token {
c.JSON(http.StatusForbidden, model.WrapperResponse{Code: 403, Msg: "Token 无效"}) c.JSON(http.StatusForbidden, model.WrapperResponse{Code: 403, Msg: "Token 无效"})
return return
} }
@@ -173,7 +178,12 @@ func (h *ConfigApiHandler) FetchChangedConfigs(c *gin.Context) {
} }
// validate token if app has token configured // validate token if app has token configured
if app.Token != "" && app.Token != req.Token { // 兼容旧版客户端把 token 放在 URL query 中的行为
token := req.Token
if token == "" {
token = c.Query("token")
}
if app.Token != "" && app.Token != token {
c.JSON(http.StatusForbidden, model.WrapperResponse{Code: 403, Msg: "Token 无效"}) c.JSON(http.StatusForbidden, model.WrapperResponse{Code: 403, Msg: "Token 无效"})
return return
} }