改造"授权","持票人"+令牌

far*_*had 49 java android retrofit server retrofit2

我正在尝试使用Retrofit2,我想添加Token到我的Header喜欢这个:
Authorization: Bearer Tokencode下面不起作用:

public interface APIService {
    @Headers({"Authorization", "Bearer "+ token})
    @GET("api/Profiles/GetProfile?id={id}")
    Call<UserProfile> getUser(@Path("id") String id);
}
Run Code Online (Sandbox Code Playgroud)

我的服务器asp.net webApi 请帮忙我该怎么办?

iag*_*een 96

您有两种选择 - 您可以将其作为参数添加到您的通话中 -

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

这可能有点烦人,因为你必须传入"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();
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,直到实现它之后我才意识到,但令牌仅在运行时才知道 - 因此我认为这是一个更好的解决方案:/sf/ask/3013609091/运行时标头/43083639#43083639 (2认同)

Ham*_*man 11

如果你想将Bearer Token添加为Header你可以做那些类型的过程..这是与Bearar Token一起工作的一种方法

在您的界面中

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

之后,您将以这种方式调用Retrofit对象

Retrofit retrofit  = new Retrofit.Builder()
                    .baseUrl("your Base URL")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

APIService client = retrofit.create(APIService.class);
Call<UserProfile> calltargetResponse = client.getUser("0034", "Bearer "+token);
calltargetResponse.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();
        }
});
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用拦截...这与之前的Answaer相似但是那个时候你只需要修改界面一点点就好

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

希望这对你有用


Far*_*med 11

基于@iagreen 解决方案 kotlin 版本,具有@Daniel Wilson 建议的不同类和结构

像这样制作 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
      }

}
Run Code Online (Sandbox Code Playgroud)

添加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)
  }

}
Run Code Online (Sandbox Code Playgroud)

登录接口和数据类实现

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)
Run Code Online (Sandbox Code Playgroud)

在任何这样的活动中调用它

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
                }
            }

        })
Run Code Online (Sandbox Code Playgroud)

有关详细信息,视频将有所帮助。


小智 8

这会将您的令牌添加到构建器,您可以在登录/注销时随时更改它。

object ApiService {
    var YOUR_TOKEN = ""

    private var retrofit: Retrofit = Retrofit.Builder()
        .baseUrl("YOUR_URL")
        .addConverterFactory(GsonConverterFactory.create())
        .client(OkHttpClient.Builder().addInterceptor { chain ->
            val request = chain.request().newBuilder().addHeader("Authorization", "Bearer ${YOUR_TOKEN}").build()
            chain.proceed(request)
        }.build())
        .build()

    var service: AppAPI = retrofit.create(AppAPI::class.java)
        private set

}
Run Code Online (Sandbox Code Playgroud)


Mor*_*Koh 6

您需要将拦截器添加到OkHttpClient.

添加一个名为 的类OAuthInterceptor

class OAuthInterceptor(private val tokenType: String, private val accessToken: String) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
        var request = chain.request()
        request = request.newBuilder().header("Authorization", "$tokenType $accessToken").build()

        return chain.proceed(request)
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,当您初始化RetrofitApiService界面时,您将需要它。

interface RetrofitApiService {
    companion object {
        private const val BASE_URL = "https://api.coursera.org/api/businesses.v1/"
        fun create(accessToken: String): RetrofitApiService {
            val client = OkHttpClient.Builder()
                    .addInterceptor(OAuthInterceptor("Bearer", accessToken))
                    .build()

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

            return retrofit.create(RetrofitApiService::class.java)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

向 Java Code Monk 致敬,并访问参考链接了解更多详细信息。 https://www.javacodemonk.com/retrofit-oauth2-authentication-okhttp-android-3b702350


Zho*_*gbo 5

最好的方法是使用新的 Authenticator API。

class TokenAuthenticator : Authenticator {
    override fun authenticate(route: Route?, response: Response): Request? {
        if (response.request.header("Authorization") != null) {
            return null
        }
        return response.request.newBuilder().header("Authorization", "Bearer " + token).build()
    }
}
OkHttpClient.Builder().authenticator(TokenAuthenticator()).build()
Run Code Online (Sandbox Code Playgroud)

参考:https://square.github.io/okhttp/recipes/#handling-authentication-kt-java