Retrofit で一部のメソッドだけに Authorization ヘッダーとトークンをつけるには……。以下のソースコードは Kotlin でコンパイルも通していない雰囲気だけのもの。
バージョンは↓。
- Retrofit 2.6.x
- OkHttp 4.0.x
↓にある方法のひとつを紹介する。
https://stackoverflow.com/questions/41078866/retrofit-authorization-bearer-token
まず単純な方法はメソッドの引数に @Headder("Authorization") token
という引数を追加すること。
interface RetrofitService { @GET("users") suspend fun getUserList(@Header("Authorization") token: String): List<User> }
Bearer
をつけたければ OkHttp の Interceptor
で header を書き換える。
val httpClient = OkHttpClient.Builder().addInterceptor(object : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() var newRequest = request.headers["Authorization"]?.let { token -> request.newBuilder().header("Authorization", "Bearer $token").build() } ?: request return chain.proceed(newRequest) } }).build() // httpClient を Retrofit の client に設定する // ...
これで動くのだけど認証の必要なメソッド (例ではgetUserList
) が token
を取るのも何だかなあと。 token
はわざわざ引数で取らなくても良いこともあるので……。
そこである種のマーカーとして Retrofit の @Headers
を使う。
interface RetrofitService { @GET("/users") @Headers(AuthorizationInterceptor.placeholder) suspend fun getUserList(): List<User> }
あとはだいたい同じで OkHttp の Interceptor
で書き換える。
class AuthorizationInterceptor: Interceptor { companion oboject { val headerName = "Authorization" val headerValue = "DUMMY" val placeholder = "$headerName: $headerValue" } override fun intercept(chain: Interceptor.Chain): Response { // token はどこかから得る // 例えばコンストラクタに context をとって SharedPreferences から……とか val token = // ... val request = chain.request() var newRequest = if (request.header(headerName) == headerValue) request.newBuilder().header("Authorization", "Bearer $token").build() else request return chain.proceed(newRequest) } } // ... val httpClient = OkHttpClient.Builder().addInterceptor(AuthorizationInterceptor()).build() // httpClient を Retrofit の client に設定する // ...
どうするのが良いのかは知らないけど一応こんな感じで動く。