hxb
2024-10-24 773b9953ad645b39a9efa8ab6d71dfc9d9e4e22e
HDLLinkPMSdk/src/main/java/com/hdl/linkpm/sdk/core/interceptor/HDLLoginInterceptor.java
New file
@@ -0,0 +1,199 @@
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 com.hdl.linkpm.sdk.utils.HDLSDKLog;
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 {
    private String TAG =HDLLoginInterceptor.class.getName();
    @NonNull
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request();
        if (!isRefreshTokenHeader(request.headers())) {
            String token = HDLLinkPMUser.getInstance().getAccessToken();
            HDLSDKLog.i(TAG, "当前请求token:"+token);
            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();
        HDLSDKLog.i(TAG, "刷新Token,当前刷新Token是:"+cacheRefreshToken);
        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) {
                        HDLSDKLog.i(TAG, "获取到刷新Token的数据,状态码:"+baseInfo.getCode());
                        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 "";
    }
}