Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,16 @@ public void refreshOrObtainNewToken(DifyServerClient difyServerClient) {
tokenLock.lock();
try {
if (refreshToken != null) {
LoginResponse response = difyServerClient.refreshToken(refreshToken);
if (response != null) {
this.accessToken = response.getAccessToken();
this.refreshToken = response.getRefreshToken();
this.csrfToken = response.getCsrfToken();
return;
try {
LoginResponse response = difyServerClient.refreshToken(refreshToken);
if (response != null) {
this.accessToken = response.getAccessToken();
this.refreshToken = response.getRefreshToken();
this.csrfToken = response.getCsrfToken();
return;
}
} catch (Exception e) {
log.warn("Failed to refresh token:{}, will attempt to login", e.getMessage());
}
}
// 如果刷新token失败或没有刷新token,则重新登录
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,20 @@ private String obtainToken(DifyServerClient difyServerClient) {
public void refreshOrObtainNewToken(DifyServerClient difyServerClient) {
String refreshToken = redisTemplate.opsForValue().get(DifyRedisKey.REFRESH_TOKEN);
if (refreshToken != null) {
LoginResponse response = difyServerClient.refreshToken(refreshToken);
if (response != null) {
String accessToken = response.getAccessToken();
redisTemplate.opsForValue().set(DifyRedisKey.ACCESS_TOKEN, accessToken);
redisTemplate.expire(DifyRedisKey.ACCESS_TOKEN, TOKEN_EXPIRE_MINUTES, TimeUnit.MINUTES);
redisTemplate.opsForValue().set(DifyRedisKey.REFRESH_TOKEN, response.getRefreshToken());
if (StrUtil.isNotEmpty(response.getCsrfToken())) {
redisTemplate.opsForValue().set(DifyRedisKey.CSRF_TOKEN, response.getCsrfToken());
try {
LoginResponse response = difyServerClient.refreshToken(refreshToken);
if (response != null) {
String accessToken = response.getAccessToken();
redisTemplate.opsForValue().set(DifyRedisKey.ACCESS_TOKEN, accessToken);
redisTemplate.expire(DifyRedisKey.ACCESS_TOKEN, TOKEN_EXPIRE_MINUTES, TimeUnit.MINUTES);
redisTemplate.opsForValue().set(DifyRedisKey.REFRESH_TOKEN, response.getRefreshToken());
if (StrUtil.isNotEmpty(response.getCsrfToken())) {
redisTemplate.opsForValue().set(DifyRedisKey.CSRF_TOKEN, response.getCsrfToken());
}
return;
}
return;
} catch (Exception e) {
log.warn("Failed to refresh token:{}, will attempt to login", e.getMessage());
}
}
// 如果刷新token失败或没有刷新token,则重新登录
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.github.guoshiqiufeng.dify.server.client;

import io.github.guoshiqiufeng.dify.core.exception.DiftClientExceptionEnum;
import io.github.guoshiqiufeng.dify.core.exception.DifyClientException;
import io.github.guoshiqiufeng.dify.server.dto.response.LoginResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -193,6 +195,67 @@ void testRefreshOrObtainNewTokenWithFailedRefresh() throws Exception {
assertEquals("new-refresh-token", storedRefreshToken);
}

@Test
@DisplayName("Test refreshOrObtainNewToken with exception thrown during refresh - should fallback to login")
void testRefreshOrObtainNewTokenWithExceptionDuringRefresh() throws Exception {
// Setup - first set initial tokens
LoginResponse initialLoginResponse = new LoginResponse();
initialLoginResponse.setAccessToken("initial-access-token");
initialLoginResponse.setRefreshToken("initial-refresh-token");
initialLoginResponse.setCsrfToken("initial-csrf-token");
when(difyServerClient.login()).thenReturn(initialLoginResponse);

// Initialize token with initial values
HttpHeaders initialHeaders = mock(HttpHeaders.class);
tokenDefault.addAuthorizationHeader(initialHeaders, difyServerClient);

// Verify initial setup
verify(difyServerClient).login();
verify(initialHeaders).setBearerAuth("initial-access-token");

// Reset mocks and prepare for refresh
reset(difyServerClient);

// Setup refresh to throw exception (simulating 401 Unauthorized)
when(difyServerClient.refreshToken("initial-refresh-token"))
.thenThrow(new DifyClientException(DiftClientExceptionEnum.UNAUTHORIZED));

// Setup new login response
LoginResponse newLoginResponse = new LoginResponse();
newLoginResponse.setAccessToken("new-access-token-after-exception");
newLoginResponse.setRefreshToken("new-refresh-token-after-exception");
newLoginResponse.setCsrfToken("new-csrf-token-after-exception");
when(difyServerClient.login()).thenReturn(newLoginResponse);

// Execute - should catch exception and fallback to login
tokenDefault.refreshOrObtainNewToken(difyServerClient);

// Verify that refreshToken was called and threw exception
verify(difyServerClient).refreshToken("initial-refresh-token");

// Verify that login was called as fallback
verify(difyServerClient).login();

// Use reflection to check internal token state - should have new tokens from login
Field accessTokenField = DifyServerTokenDefault.class.getDeclaredField("accessToken");
accessTokenField.setAccessible(true);
String accessToken = (String) accessTokenField.get(tokenDefault);
assertEquals("new-access-token-after-exception", accessToken,
"Access token should be updated with new token from login after refresh exception");

Field refreshTokenField = DifyServerTokenDefault.class.getDeclaredField("refreshToken");
refreshTokenField.setAccessible(true);
String storedRefreshToken = (String) refreshTokenField.get(tokenDefault);
assertEquals("new-refresh-token-after-exception", storedRefreshToken,
"Refresh token should be updated with new token from login after refresh exception");

Field csrfTokenField = DifyServerTokenDefault.class.getDeclaredField("csrfToken");
csrfTokenField.setAccessible(true);
String csrfToken = (String) csrfTokenField.get(tokenDefault);
assertEquals("new-csrf-token-after-exception", csrfToken,
"CSRF token should be updated with new token from login after refresh exception");
}

@Test
@DisplayName("Test executeWithRetry with successful operation")
void testExecuteWithRetrySuccessful() {
Expand Down
Loading