mirror of
https://github.com/PowerJob/PowerJob.git
synced 2025-07-17 00:00:04 +08:00
fix: PowerJobClient refresh token failed when jwt expired
This commit is contained in:
parent
44ef76328b
commit
85f5faaaac
@ -3,6 +3,7 @@ package tech.powerjob.client.service.impl;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.powerjob.client.ClientConfig;
|
||||
import tech.powerjob.client.TypeStore;
|
||||
import tech.powerjob.client.module.AppAuthRequest;
|
||||
@ -24,6 +25,7 @@ import java.util.Map;
|
||||
* @author tjq
|
||||
* @since 2024/2/21
|
||||
*/
|
||||
@Slf4j
|
||||
abstract class AppAuthClusterRequestService extends ClusterRequestService {
|
||||
|
||||
protected AppAuthResult appAuthResult;
|
||||
@ -49,6 +51,7 @@ abstract class AppAuthClusterRequestService extends ClusterRequestService {
|
||||
}
|
||||
|
||||
// 否则请求无效,刷新鉴权后重新请求
|
||||
log.warn("[PowerJobClient] auth failed[authStatus: {}], try to refresh the auth info", authStatus);
|
||||
refreshAppAuthResult();
|
||||
httpResponse = doRequest(path, powerRequestBody);
|
||||
|
||||
@ -83,12 +86,14 @@ abstract class AppAuthClusterRequestService extends ClusterRequestService {
|
||||
AppAuthRequest appAuthRequest = buildAppAuthRequest();
|
||||
HttpResponse httpResponse = clusterHaRequest(OpenAPIConstant.AUTH_APP, PowerRequestBody.newJsonRequestBody(appAuthRequest));
|
||||
if (!httpResponse.isSuccess()) {
|
||||
throw new PowerJobException("auth_app_exception!");
|
||||
throw new PowerJobException("AUTH_APP_EXCEPTION!");
|
||||
}
|
||||
ResultDTO<AppAuthResult> authResultDTO = JSONObject.parseObject(httpResponse.getResponse(), TypeStore.APP_AUTH_RESULT_TYPE);
|
||||
if (!authResultDTO.isSuccess()) {
|
||||
throw new PowerJobException("auth_failed:" + authResultDTO.getMessage());
|
||||
throw new PowerJobException("AUTH_FAILED_" + authResultDTO.getMessage());
|
||||
}
|
||||
|
||||
log.warn("[PowerJobClient] refresh auth info successfully!");
|
||||
this.appAuthResult = authResultDTO.getData();
|
||||
}
|
||||
|
||||
|
@ -126,10 +126,10 @@ public class ClusterRequestServiceOkHttp3Impl extends AppAuthClusterRequestServi
|
||||
// 设置读取超时时间
|
||||
.readTimeout(Optional.ofNullable(config.getReadTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
// 设置写的超时时间
|
||||
.writeTimeout(Optional.ofNullable(config.getReadTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
.writeTimeout(Optional.ofNullable(config.getWriteTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
// 设置连接超时时间
|
||||
.connectTimeout(Optional.ofNullable(config.getReadTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
.callTimeout(Optional.ofNullable(config.getReadTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS);
|
||||
.connectTimeout(Optional.ofNullable(config.getConnectionTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
.callTimeout(Optional.ofNullable(config.getConnectionTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import tech.powerjob.client.IPowerJobClient;
|
||||
import tech.powerjob.client.PowerJobClient;
|
||||
@ -16,6 +17,6 @@ public class ClientInitializer {
|
||||
|
||||
@BeforeAll
|
||||
public static void initClient() throws Exception {
|
||||
powerJobClient = new PowerJobClient("127.0.0.1:7700", "powerjob-worker-samples", "powerjob12345");
|
||||
powerJobClient = new PowerJobClient(Lists.newArrayList("127.0.0.1:7700", "127.0.0.1:7701"), "powerjob-worker-samples", "powerjob123");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import tech.powerjob.common.response.JobInfoDTO;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import tech.powerjob.common.utils.CommonUtils;
|
||||
|
||||
/**
|
||||
* 测试容灾能力
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/11
|
||||
*/
|
||||
@Slf4j
|
||||
public class TestClusterHA extends ClientInitializer {
|
||||
|
||||
@Test
|
||||
void testHa() {
|
||||
// 人工让 server 启停
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
|
||||
CommonUtils.easySleep(100);
|
||||
|
||||
ResultDTO<JobInfoDTO> jobInfoDTOResultDTO = powerJobClient.fetchJob(1L);
|
||||
|
||||
log.info("[TestClusterHA] response: {}", JSONObject.toJSONString(jobInfoDTOResultDTO));
|
||||
|
||||
if (!jobInfoDTOResultDTO.isSuccess()) {
|
||||
throw new RuntimeException("request failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -31,10 +31,20 @@ public enum ErrorCodes {
|
||||
|
||||
INCORRECT_PASSWORD("-400", "INCORRECT_PASSWORD"),
|
||||
|
||||
/**
|
||||
* 非法令牌
|
||||
*/
|
||||
INVALID_TOKEN("-401", "INVALID_TOKEN"),
|
||||
|
||||
/**
|
||||
* 无效 APP(无法找到 app)
|
||||
*/
|
||||
INVALID_APP("-402", "INVALID_APP"),
|
||||
|
||||
/**
|
||||
* 令牌过期
|
||||
*/
|
||||
TOKEN_EXPIRED("-403", "TOKEN_EXPIRED"),
|
||||
|
||||
/**
|
||||
* 系统内部异常
|
||||
*/
|
||||
|
@ -12,5 +12,5 @@ public interface JwtService {
|
||||
|
||||
String build(Map<String, Object> body, String extraSk);
|
||||
|
||||
Map<String, Object> parse(String jwt, String extraSk);
|
||||
ParseResult parse(String jwt, String extraSk);
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package tech.powerjob.server.auth.jwt;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 解析结果
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/11
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ParseResult implements Serializable {
|
||||
|
||||
/**
|
||||
* 解析状态
|
||||
*/
|
||||
private Status status;
|
||||
/**
|
||||
* 解析结果
|
||||
*/
|
||||
private Map<String, Object> result;
|
||||
|
||||
private String msg;
|
||||
|
||||
public enum Status {
|
||||
SUCCESS,
|
||||
EXPIRED,
|
||||
FAILED
|
||||
}
|
||||
}
|
@ -4,10 +4,13 @@ import com.google.common.collect.Maps;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tech.powerjob.server.auth.jwt.JwtService;
|
||||
import tech.powerjob.server.auth.jwt.ParseResult;
|
||||
import tech.powerjob.server.auth.jwt.SecretProvider;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -22,6 +25,7 @@ import java.util.UUID;
|
||||
* @author tjq
|
||||
* @since 2023/3/20
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class JwtServiceImpl implements JwtService {
|
||||
|
||||
@ -63,8 +67,16 @@ public class JwtServiceImpl implements JwtService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> parse(String jwt, String extraSk) {
|
||||
return innerParse(fetchSk(extraSk), jwt);
|
||||
public ParseResult parse(String jwt, String extraSk) {
|
||||
try {
|
||||
Map<String, Object> parseResult = innerParse(fetchSk(extraSk), jwt);
|
||||
return new ParseResult().setStatus(ParseResult.Status.SUCCESS).setResult(parseResult);
|
||||
} catch (ExpiredJwtException expiredJwtException) {
|
||||
return new ParseResult().setStatus(ParseResult.Status.EXPIRED).setMsg(expiredJwtException.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.warn("[JwtService] parse jwt[{}] with extraSk[{}] failed", jwt, extraSk, e);
|
||||
return new ParseResult().setStatus(ParseResult.Status.FAILED).setMsg(ExceptionUtils.getMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
private String fetchSk(String extraSk) {
|
||||
|
@ -236,7 +236,7 @@ public class PowerJobLoginServiceImpl implements PowerJobLoginService {
|
||||
if (StringUtils.isEmpty(jwtStr)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final Map<String, Object> jwtBodyMap = jwtService.parse(jwtStr, null);
|
||||
final Map<String, Object> jwtBodyMap = jwtService.parse(jwtStr, null).getResult();
|
||||
|
||||
if (MapUtils.isEmpty(jwtBodyMap)) {
|
||||
return Optional.empty();
|
||||
|
@ -12,6 +12,7 @@ import tech.powerjob.common.enums.ErrorCodes;
|
||||
import tech.powerjob.common.exception.PowerJobException;
|
||||
import tech.powerjob.server.auth.common.utils.HttpServletUtils;
|
||||
import tech.powerjob.server.auth.jwt.JwtService;
|
||||
import tech.powerjob.server.auth.jwt.ParseResult;
|
||||
import tech.powerjob.server.core.service.AppInfoService;
|
||||
import tech.powerjob.server.persistence.remote.model.AppInfoDO;
|
||||
|
||||
@ -53,7 +54,15 @@ public class OpenApiSecurityServiceImpl implements OpenApiSecurityService {
|
||||
throw new PowerJobException(ErrorCodes.OPEN_API_AUTH_FAILED, "token_is_empty");
|
||||
}
|
||||
|
||||
Map<String, Object> jwtResult = jwtService.parse(token, null);
|
||||
ParseResult parseResult = jwtService.parse(token, null);
|
||||
switch (parseResult.getStatus()) {
|
||||
case EXPIRED:
|
||||
throw new PowerJobException(ErrorCodes.TOKEN_EXPIRED, parseResult.getMsg());
|
||||
case FAILED:
|
||||
throw new PowerJobException(ErrorCodes.INVALID_TOKEN, parseResult.getMsg());
|
||||
}
|
||||
|
||||
Map<String, Object> jwtResult = parseResult.getResult();
|
||||
|
||||
Long appIdFromJwt = MapUtils.getLong(jwtResult, JWT_KEY_APP_ID);
|
||||
String passwordFromJwt = MapUtils.getString(jwtResult, JWT_KEY_APP_PASSWORD);
|
||||
|
Loading…
x
Reference in New Issue
Block a user