くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Retrofit2でAuthorizationヘッダを自動で設定する

AndroidRetrofit2を使うときに、
アクセストークンを毎回設定するのはめんどくさいので、
よい方法はないかなと調べてみたときの備忘録(*´ω`*)

OkHttpClientのInterceptorで挿入するとよいっぽい。

ApiClientインターフェースの作成

ヘッダーが必要な場合のみ、@Headers(...)を設定する形にしたい。

public interface ApiClient {
  @GET("/api/foo")
  Single<GetFooResponse> getFoo();
  
  @POST("/api/foo")
  @Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
  Single<PostFooResponse> postFoo();
} 

AuthorizationInterceptorの実装

実態はこんな感じ。
リクエストのAuthorizationヘッダをみて、ダミーの値を本物に差し替える感じ。

import androidx.annotation.NonNull;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class AuthorizationInterceptor implements Interceptor {
    private static final String HEADER_NAME = "Authorization";
    private static final String HEADER_VALUE = "DUMMY";
    public static final String HEADER_PLACEHOLDER = HEADER_NAME + ": " + HEADER_VALUE;

    @NonNull
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        try {
            String token = getToken();
            Request request = chain.request();

            // トークンがなければ、何もしない
            if (token == null || token.isEmpty()) return chain.proceed(request);

            // ヘッダにHEADER_PLACEHOLDERがなければ、何もしない
            if (request.header(HEADER_NAME) == null) chain.proceed(request);
            if (!request.header(HEADER_NAME).equals(HEADER_VALUE)) return chain.proceed(request);

            // "Authorization"ヘッダをtokenに設定
            Request newRequest = request.newBuilder()
                    .header(HEADER_NAME, token)
                    .build();
            return chain.proceed(newRequest);
        } catch (Exception e) {
            return chain.proceed(chain.request());
        }
    }

    protected String getToken() {
        return "...トークンを返す";
    }
}

Retrofitインスタンスの生成

あとはAuthorizationInterceptorを設定して、
Retrofitのインスタンスの生成すればOK

protected Retrofit getRetrofit(String baseUrl) {
    OkHttpClient okHttpClient = 
        new OkHttpClient.Builder()
        // Authorization Headerの自動付与
        .addInterceptor(new AuthorizationInterceptor())
        .build();
      
    return new Retrofit.Builder()
            .baseUrl("...")
            .client(okHttpClient)
            .build();
}

以上!! 便利(*´ω`*)

参考にしたサイト様