mac
2023-11-22 3f41182984d69d7fae703776edd1591f48dff93f
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package com.hdl.linkpm.sdk.core.interceptor;
 
import android.text.TextUtils;
import android.util.Log;
 
import androidx.annotation.NonNull;
 
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import com.hdl.hdlhttp.HxHttpConfig;
import com.hdl.linkpm.sdk.core.api.HDLCloudUserApi;
import com.hdl.linkpm.sdk.core.code.HDLCloudCode;
import com.hdl.linkpm.sdk.core.response.BaseInfo;
import com.hdl.linkpm.sdk.user.HDLLinkPMUser;
import com.hdl.linkpm.sdk.user.bean.HDLLoginBean;
import com.hdl.linkpm.sdk.utils.HDLGsonUtils;
 
import java.io.IOException;
import java.nio.charset.Charset;
 
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
 
/**
 * Created by Tong on 2021/11/2.
 */
public class HDLLoginInterceptor implements Interceptor {
 
    @NonNull
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request();
        if (!isRefreshTokenHeader(request.headers())) {
            String token = HDLLinkPMUser.getInstance().getAccessToken();
            if (!TextUtils.isEmpty(token)) {
                Request processRequest = addToken(request, token);
                Response processResponse = chain.proceed(processRequest);
                return disposeToken(chain, processRequest, processResponse);
            }
        }
        return chain.proceed(request);
    }
 
    @NonNull
    private Response disposeToken(Chain chain, Request request, Response response) {
        try {
 
//            ResponseBody responseBody2 = response.body();
//            BufferedSource source2 = responseBody2.source();
//            source2.request(Long.MAX_VALUE);
//            Buffer buffer2 = source2.getBuffer().clone();
//            String respString2 = buffer2.readString(Charset.defaultCharset());
            //http标准状态码
            if (401 == response.code() || 402 == response.code() || 403 == response.code()) {
                final String token = refreshToken();
                if (!TextUtils.isEmpty(token)) {
                    return chain.proceed(addToken(request, token));
                }
 
            } else if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                if (responseBody != null) {
                    BufferedSource source = responseBody.source();
                    source.request(Long.MAX_VALUE);
                    Buffer buffer = source.getBuffer().clone();
                    String respString = buffer.readString(Charset.defaultCharset());
                    JsonObject object = JsonParser.parseString(respString).getAsJsonObject();
                    int code = object.get("code").getAsInt();
                    //1.判断token是否过期是否需要刷新token
                    if (isTokenTimeoutByCode(code)) {
                        final String token = refreshToken();
                        if (!TextUtils.isEmpty(token)) {
                            return chain.proceed(addToken(request, token));
                        }
                    }
                    //2.判断Token是否错误 发送登出处理通知
                    if (isTokenNeedReLoginByCode(code)) {
                        //3.清空登录信息并发出重新登录通知
                        HDLLinkPMUser.getInstance().logout(0);
                    }
                }
 
            }
 
        } catch (Exception e) {
            Log.d("HDL===>", "disposeToken: 失败," + e);
        }
        return response;
    }
 
    /**
     * 根据code判断token是否失效 需要刷新重新token
     *
     * @param code 业务code
     * @return ture 失效
     */
    private boolean isTokenTimeoutByCode(int code) {
        return HDLCloudCode.TOKEN_TIMEOUT == code;
    }
 
    /**
     * 根据code判断token是否失效 需要重新登录的
     *
     * @param code 业务code
     * @return ture 失效
     */
    private boolean isTokenNeedReLoginByCode(int code) {
        return HDLCloudCode.RE_LOGIN == code
                || HDLCloudCode.TOKEN_NOT_STANDARD == code
                || HDLCloudCode.NO_TOKEN == code
                || HDLCloudCode.CODE_TOKEN_ERROR_10006 == code
                || HDLCloudCode.CODE_TOKEN_ERROR_10009 == code;
    }
 
 
    /**
     * 是否存在刷新头
     */
    private boolean isRefreshTokenHeader(Headers headers) {
        String signHeader = headers.get(HDLSmartHeader.REFRESH_TOKEN_HEADER);
        return !TextUtils.isEmpty(signHeader);
    }
 
    private Request addToken(Request request, String token) {
        return request.newBuilder()
                .removeHeader("Authorization")
                .build()
                .newBuilder()
                .method(request.method(), request.body())
                .addHeader("Authorization", token)
                .build();
    }
 
    /**
     * 拦截器EncryptInterceptor会处理加密
     *
     * @return token
     */
    private String refreshToken() {
        final String cacheRefreshToken = HDLLinkPMUser.getInstance().getRefreshToken();
        final String regionUrl = HDLCloudUserApi.getRequestUrl(HDLCloudUserApi.POST_LOGIN);
        final OkHttpClient client = HxHttpConfig.getInstance().getClient();
        Request.Builder builder = new Request.Builder();
 
        final JsonObject json = new JsonObject();
        json.addProperty("refreshToken", cacheRefreshToken);
        json.addProperty("grantType", "refresh_token");
 
        final RequestBody requestBody = RequestBody.create(json.toString(), MediaType.parse("application/json;charset=UTF-8"));
        builder.post(requestBody);
        builder.url(regionUrl);
        builder.addHeader(HDLSmartHeader.REFRESH_TOKEN_HEADER, "0");
        try {
            Response response = client.newCall(builder.build()).execute();
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                if (responseBody != null) {
                    BufferedSource source = responseBody.source();
                    source.request(Long.MAX_VALUE);
                    Buffer buffer = source.getBuffer().clone();
                    String respString = buffer.readString(Charset.defaultCharset());
                    BaseInfo<HDLLoginBean> baseInfo = HDLGsonUtils.fromJson(respString, new TypeToken<BaseInfo<HDLLoginBean>>() {
                    }.getType());
                    if (baseInfo != null) {
                        if (baseInfo.getCode() == HDLCloudCode.SUCCEED) {
                            if (baseInfo.getData() != null) {
                                HDLLoginBean loginBean = baseInfo.getData();
                                HDLLinkPMUser.getInstance().updateRefreshToken(loginBean);
                                return loginBean.getHeaderPrefix() + loginBean.getAccessToken();
                            }
                        } else {
                            //refreshToken也过期的话,则发出登出处理通知,重新登录
                            //清空登录信息并发出重新登录通知
                            HDLLinkPMUser.getInstance().logout(0);
                        }
                    }
                }
            }
        } catch (Exception ignored) {
            Log.d("HDL===>", "refreshToken: 失败");
        }
        return "";
    }
}