web-dev-qa-db-ja.com

後付け「認可」、「ベアラー」+トークン

Retrofit (2)を使用しようとしています。TokenHeaderに追加します。
Authorization: Bearer Tokenが、以下のcodeは機能しません。

public interface APIService {

        @Headers({
                    "Authorization", "Bearer "+ token
            })

    @GET("api/Profiles/GetProfile?id={id}")
    Call<UserProfile> getUser(@Path("id") String id);
}

私のサーバーはasp.net webApiです。どうすればいいですか?

45
farshad

2つの選択肢があります-呼び出しのパラメーターとして追加できます-

@GET("api/Profiles/GetProfile?id={id}")
Call<UserProfile> getUser(@Path("id") String id, @Header("Authorization") String authHeader);

呼び出しごとに"Bearer" + tokenを渡す必要があるため、これは少し面倒です。これは、トークンを必要とする呼び出しがあまりない場合に適しています。

すべてのリクエストにヘッダーを追加する場合は、okhttpインターセプターを使用できます-

OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
      @Override
      public Response intercept(Chain chain) throws IOException {
        Request newRequest  = chain.request().newBuilder()
            .addHeader("Authorization", "Bearer " + token)
            .build();
        return chain.proceed(newRequest);
      }
    }).build();

Retrofit retrofit = new Retrofit.Builder()
    .client(client)
    .baseUrl(/** your url **/)
    .addConverterFactory(GsonConverterFactory.create())
    .build();
84
iagreen

bearer Tokenをヘッダーとして追加したい場合は、これらのタイプのプロセスを実行できます。これはBearar Tokenと連携する1つの方法です

インターフェイスで

@Headers({ "Content-Type: application/json;charset=UTF-8"})
    @GET("api/Profiles/GetProfile")
    Call<UserProfile> getUser(@Query("id") String id, @Header("Authorization") String auth);

その後、この方法でRetrofitオブジェクトを呼び出します

Retrofit retrofit  = new Retrofit.Builder()
                .baseUrl("your Base URL")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        APIService client = retrofit.create(APIService.class);
        Call<UserProfile> calltargetResponce = client.getUser("0034", "Bearer "+token);
        calltargetResponce.enqueue(new Callback<UserProfile>() {
            @Override
            public void onResponse(Call<UserProfile> call, retrofit2.Response<UserProfile> response) {
                UserProfile UserResponse = response.body();
                Toast.makeText(this, " "+response.body(), Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onFailure(Call<UserProfile> call, Throwable t) {
                //Toast.makeText(this, "Failed ", Toast.LENGTH_SHORT).show();
            }
        });

別の方法はインターセプトを使用することです...これは以前のAnswaerに似ていますが、そのときはインターフェイスを少し変更する必要があります

@Headers({ "Content-Type: application/json;charset=UTF-8"})
    @GET("api/Profiles/GetProfile")
    Call<UserProfile> getUser(@Query("id") String id); 

これがあなたのために働くことを願っています

9
Hamza Rahman

@Daniel Wilsonによって提案された異なるクラスと構造を持つ@iagreenソリューションkotlinバージョンに基づく

このようなRetrofitインスタンスを作成します

object RetrofitClientInstance {
   private var retrofit: Retrofit? = null
   private val BASE_URL = "http://yoururl"


    val retrofitInstance: Retrofit?
        get() {
            if (retrofit == null) {
                var client = OkHttpClient.Builder()
                      .addInterceptor(ServiceInterceptor())
                      //.readTimeout(45,TimeUnit.SECONDS)
                      //.writeTimeout(45,TimeUnit.SECONDS)
                        .build()

                retrofit = Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .client(client)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build()

            }
            return retrofit
      }

}

以下のようなServiceInterceptorクラスを追加します

class ServiceInterceptor : Interceptor{

  var token : String = "";

  fun Token(token: String ) {
     this.token = token;
  }

  override fun intercept(chain: Interceptor.Chain): Response {
    var request = chain.request()

    if(request.header("No-Authentication")==null){
        //val token = getTokenFromSharedPreference();
        //or use Token Function
        if(!token.isNullOrEmpty())
        {
            val finalToken =  "Bearer "+token
            request = request.newBuilder()
                    .addHeader("Authorization",finalToken)
                    .build()
        }

    }

    return chain.proceed(request)
  }

}

ログインインターフェイスとデータクラスの実装

interface Login {
  @POST("Login")
  @Headers("No-Authentication: true")
  fun login(@Body value: LoginModel): Call<LoginResponseModel>



  @POST("refreshToken")
  fun refreshToken(refreshToken: String): 
      Call<APIResponse<LoginResponseModel>>
}

data class LoginModel(val Email:String,val Password:String)
data class LoginResponseModel (val token:String,val 
         refreshToken:String)

このようなアクティビティでこれを呼び出します

val service = RetrofitClientInstance.retrofitInstance?.create(Login::class.Java)
val refreshToken = "yourRefreshToken"
val call = service?.refreshToken(refreshToken)
        call?.enqueue(object: Callback<LoginResponseModel>{
            override fun onFailure(call: Call<LoginResponseModel>, t: Throwable) {
                print("throw Message"+t.message)
                Toast.makeText(applicationContext,"Error reading JSON",Toast.LENGTH_LONG).show()
            }

            override fun onResponse(call: Call<LoginResponseModel>, response: Response<LoginResponseModel>) {
                val body = response?.body()
                if(body!=null){
                    //do your work
                }
            }

        })

詳細については this videoが役立ちます。

1
Faraz Ahmed