You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在Retrofit中携带Basic Auth及指定Header发送POST请求?

问题描述

我希望在代码中发送携带Basic Auth的POST请求,Postman中已经配置了对应的Basic Auth认证(用户名EBA,令牌34242353453456563DSFS)。

我的ApiInterface类代码如下:

@FormUrlEncoded
@POST("GetBarcodeDetail")
Call<PreliminaryGoodsAcceptResponse> PRELIMINARY_GOODS_ACCEPT_RESPONSE_CALL(
    @Field("ProcName") String procName,
    @Field("Barcode") String barcode,
    @Field("LangCode") String langCode
);

我的ApiClient类代码如下:

public class ApiClient {
    public static final String BASE_URL = "http://192.**********";
    private static Retrofit retrofit = null;
    private static OkHttpClient sClient;

    public static Retrofit getClient() {
        if(sClient == null) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            sClient = new OkHttpClient.Builder()
                    .addInterceptor(new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT))
                    .addInterceptor(interceptor)
                    .build();
        }
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(sClient)
                    .build();
        }
        return retrofit;
    }
}

请问如何通过添加Header(Username: EBA,Token: 34242353453456563DSFS)来发送该POST请求?

解决方案

针对你的需求,有两种常用的方式来添加Basic Auth认证头,我分别给你说明:

方式一:在单个接口方法中添加Header

如果你只需要给这一个接口添加认证,可以直接在ApiInterface的方法上添加注解,分两种场景:

固定认证信息(适合令牌不变的场景)

直接用@Headers注解添加固定的认证头,这里的认证值是EBA:34242353453456563DSFS经过Base64编码后的结果:

@FormUrlEncoded
@POST("GetBarcodeDetail")
@Headers({
    "Authorization: Basic RUJBOjM0MjQyMzUzNDUzNDU2NTYzRkNGUw=="
})
Call<PreliminaryGoodsAcceptResponse> PRELIMINARY_GOODS_ACCEPT_RESPONSE_CALL(
    @Field("ProcName") String procName,
    @Field("Barcode") String barcode,
    @Field("LangCode") String langCode
);

动态传递认证信息(适合令牌可能变化的场景)

@Header注解动态接收认证头参数,调用时再构造传入:

@FormUrlEncoded
@POST("GetBarcodeDetail")
Call<PreliminaryGoodsAcceptResponse> PRELIMINARY_GOODS_ACCEPT_RESPONSE_CALL(
    @Header("Authorization") String authHeader,
    @Field("ProcName") String procName,
    @Field("Barcode") String barcode,
    @Field("LangCode") String langCode
);

调用示例:

// 构造认证头
String credentials = "EBA:34242353453456563DSFS";
String authHeader = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
// 发起请求
apiInterface.PRELIMINARY_GOODS_ACCEPT_RESPONSE_CALL(authHeader, procName, barcode, langCode);

方式二:全局添加认证拦截器(推荐)

如果你的多个接口都需要Basic Auth认证,更推荐在OkHttpClient中添加拦截器,自动给所有请求加上认证头,不用每个接口单独处理:

修改你的ApiClient类,添加认证拦截器:

public class ApiClient {
    public static final String BASE_URL = "http://192.**********";
    private static Retrofit retrofit = null;
    private static OkHttpClient sClient;

    public static Retrofit getClient() {
        if(sClient == null) {
            // 构造Basic Auth认证头
            String credentials = "EBA:34242353453456563DSFS";
            final String authHeader = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);

            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            
            sClient = new OkHttpClient.Builder()
                    .addInterceptor(new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT))
                    .addInterceptor(interceptor)
                    // 添加全局认证拦截器
                    .addInterceptor(chain -> {
                        Request originalRequest = chain.request();
                        Request authenticatedRequest = originalRequest.newBuilder()
                                .header("Authorization", authHeader)
                                .build();
                        return chain.proceed(authenticatedRequest);
                    })
                    .build();
        }
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(sClient)
                    .build();
        }
        return retrofit;
    }
}

修改后,所有通过这个ApiClient创建的接口请求都会自动带上Basic Auth认证头,无需额外处理。如果你的令牌是动态获取的(比如登录后返回),可以把authHeader改成从SharedPreferences等存储中动态读取的方式。

内容的提问来源于stack exchange,提问作者cartoonworld

火山引擎 最新活动