WangHan
2024-09-12 d5855a4926926698b740bc6c7ba489de47adb68b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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;
import tech.powerjob.client.module.AppAuthResult;
import tech.powerjob.client.service.HttpResponse;
import tech.powerjob.client.service.PowerRequestBody;
import tech.powerjob.common.OpenAPIConstant;
import tech.powerjob.common.enums.EncryptType;
import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.common.response.ResultDTO;
import tech.powerjob.common.utils.DigestUtils;
import tech.powerjob.common.utils.MapUtils;
 
import java.util.Map;
 
/**
 * 封装鉴权相关逻辑
 *
 * @author tjq
 * @since 2024/2/21
 */
@Slf4j
abstract class AppAuthClusterRequestService extends ClusterRequestService {
 
    protected AppAuthResult appAuthResult;
 
    public AppAuthClusterRequestService(ClientConfig config) {
        super(config);
    }
 
 
    @Override
    public String request(String path, PowerRequestBody powerRequestBody) {
        // 若不存在 appAuthResult,则首先进行鉴权
        if (appAuthResult == null) {
            refreshAppAuthResult();
        }
 
        HttpResponse httpResponse = doRequest(path, powerRequestBody);
 
        // 如果 auth 成功,则代表请求有效,直接返回
        String authStatus = MapUtils.getString(httpResponse.getHeaders(), OpenAPIConstant.RESPONSE_HEADER_AUTH_STATUS);
        if (Boolean.TRUE.toString().equalsIgnoreCase(authStatus)) {
            return httpResponse.getResponse();
        }
 
        // 否则请求无效,刷新鉴权后重新请求
        log.warn("[PowerJobClient] auth failed[authStatus: {}], try to refresh the auth info", authStatus);
        refreshAppAuthResult();
        httpResponse = doRequest(path, powerRequestBody);
 
        // 只要请求不失败,直接返回(如果鉴权失败则返回鉴权错误信息,server 保证 response 永远非空)
        return httpResponse.getResponse();
    }
 
    private HttpResponse doRequest(String path, PowerRequestBody powerRequestBody) {
 
        // 添加鉴权信息
        Map<String, String> authHeaders = buildAuthHeader();
        powerRequestBody.addHeaders(authHeaders);
 
        HttpResponse httpResponse = clusterHaRequest(path, powerRequestBody);
 
        // 任何请求不成功,都直接报错
        if (!httpResponse.isSuccess()) {
            throw new PowerJobException("REMOTE_SERVER_INNER_EXCEPTION");
        }
        return httpResponse;
    }
 
    private Map<String, String> buildAuthHeader() {
        Map<String, String> authHeader = Maps.newHashMap();
        authHeader.put(OpenAPIConstant.REQUEST_HEADER_APP_ID, String.valueOf(appAuthResult.getAppId()));
        authHeader.put(OpenAPIConstant.REQUEST_HEADER_ACCESS_TOKEN, appAuthResult.getToken());
        return authHeader;
    }
 
    @SneakyThrows
    private void refreshAppAuthResult() {
        AppAuthRequest appAuthRequest = buildAppAuthRequest();
        HttpResponse httpResponse = clusterHaRequest(OpenAPIConstant.AUTH_APP, PowerRequestBody.newJsonRequestBody(appAuthRequest));
        if (!httpResponse.isSuccess()) {
            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());
        }
 
        log.warn("[PowerJobClient] refresh auth info successfully!");
        this.appAuthResult = authResultDTO.getData();
    }
 
    protected AppAuthRequest buildAppAuthRequest() {
        AppAuthRequest appAuthRequest = new AppAuthRequest();
        appAuthRequest.setAppName(config.getAppName());
        appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword()));
        appAuthRequest.setEncryptType(EncryptType.MD5.getCode());
        return appAuthRequest;
    }
}