当前位置: 首页 > 知识库问答 >
问题:

Retrofit2授权-访问令牌的全局拦截器

洪浩波
2023-03-14

我正在尝试使用Retrofit2,我想将Token添加到我的Header像这样:

授权:无记名令牌但下面的code不起作用:

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

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

共有3个答案

汲雅珺
2023-03-14

基于@Daniel Wilson建议的具有不同类和结构的@igreen解决方案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
                }
            }

        })

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

慎建本
2023-03-14

如果要将承载令牌添加为标头,可以执行这些类型的处理。

这是使用无记名令牌的一种方法

在您的界面中

@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> 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();
        }
});

另一种方法是使用拦截,这类似于以前的答案。但是,那个时候你只需要修改界面就好了。

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

希望这对你有用。

华泳
2023-03-14

您有两个选择--可以将其作为参数添加到调用中--

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

这可能有点烦人,因为您必须在每次调用中都传入“承载”令牌。如果您没有太多需要令牌的调用,这很合适。

如果要将标头添加到所有请求中,可以使用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();
 类似资料:
  • 我遇到了使用文档签名 API 的第一个障碍,需要一些帮助。 我将docusignrestapi集合导入到Postman中。我设置了iKey、iSec、encodedKeys和codeFromUrl变量。 当尝试发送'01-授权代码授予访问令牌'post API时,我每次都得到以下响应。 我尝试从Postman中删除所有内容,包括环境,并从DocuSign中删除该应用程序,然后重新开始,以便我的所有

  • 我想避开keycloak登录页面。我将这个“避免keycloak默认登录页面和使用项目登录页面”链接引用到“http://localhost:5555/auth/realms/master/protocol/openid-connect/token”链接,并能够使用post方法获得访问令牌。 在此步骤中获得访问令牌后,提到要传递以下头部 标题:{ 但是不清楚将访问令牌传递到哪里,响应是什么,请求类

  • 我想要一些关于如何在隐式授予流中使用ID令牌和访问令牌的澄清。我有一个使用msal.js for Angular包的Angular SPA和一个Web API。API不调用任何外部服务,如MSFT Graph。后端仅使用JWT中的角色声明来建立对API功能的RBAC授权。 这个文档写着:https://docs.microsoft.com/en-us/azure/active-directory/

  • 我目前正在学习OAuth 2.0和OpenID Connect,我对授权服务器和访问令牌有疑问。规范将授权服务器定义为: 服务器在成功验证资源所有者并获得授权后向客户端发放访问令牌。 因此,据我所知,客户端将用户重定向到授权服务器,用户在授权服务器上进行身份验证,授权服务器向客户端发出访问令牌。 现在有一件事发生了,直到现在我才明白。有两种可能的方法来理解这一点,我正在努力找到正确的方法: > 授

  • 定义的新集成密钥9xxx7e null 但仍然得到401的回应内容:

  • null 我尝试将@priority(interceptor.priority.platform_beform)和@prematching也放入我的过滤器中,但即使是在OIDC启动后也会调用。 另外,是否有任何方法支持扩展quarkus oidc逻辑以包括自定义代码? 我无法获得oidc和keycloak-auth拦截器的优先级(知道这些可以帮助我决定过滤器的优先级)。请帮忙。