Retrofit2 - 无法通过动态URL获得webAPI的基本身份验证

时间:2016-12-21 02:02:03

标签: android json basic-authentication retrofit2

我熟悉如何将动态网址与Retrofit2一起使用,但是在发送用户名时遇到问题&请求中的密码。 webAPI通过输入URL工作,屏幕上出现登录提示,用于输入用户名&密码,验证后显示JSON响应。接口是为动态URL定义的:

@GET
public Call<User> getJSON(@Url String string);

我的要求如下:

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    LoginService service = retrofit.create(LoginService.class);

    Call<User> call = service.getJSON("https://username:password@api.url.com/");

    call.enqueue(new Callback<User>() {
        @Override
        public void onResponse(Call<User> call, retrofit2.Response<User> response) {
            System.out.println("Response status code: " + response.code());

我确定网址是正确的,因为它在浏览器和网络中有效。但我不断收到用户名和错误的错误密码不正确吗?

I/System.out: Response status code: 401

另外,据我所知,我只能使用@GET而不是@POST,因为每当我尝试@POST时,响应代码为:

I/System.out: Response status code: 405

起初我尝试使用编码标记跟踪类似于this post的内容,因为它是如何使用@PATH&amp; amp; @URL与Retrofit2但没有取得任何成功。这就是为什么我尝试使用用户名:password @ prepend到URL。大多数其他示例都使用@POST方法。

有关如何进行身份验证的任何反馈或想法?感谢

2 个答案:

答案 0 :(得分:1)

不确定如何在改造中执行此操作,但您可以通过OkHttp拦截器添加它 -

OkHttpClient client = new OkHttpClient().newBuilder().addNetworkInterceptor(
    new Interceptor() {
      @Override
      public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();
        HttpUrl url = request.url();
        url = url.newBuilder().username("username").password("password").build();
        Request newRequest = request.newBuilder().url(url).build();
        return chain.proceed(newRequest);
      }
    }
).build();

务必将此客户端添加到您的改造实例 -

Retrofit retrofit = new Retrofit.Builder()
        .client(client)
        .baseUrl(API_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

答案 1 :(得分:0)

使用Retrofit2进行基本身份验证的另一种方法是将身份验证字符串作为参数传递给您的接口方法。

因此,您可以将方法签名更改为:

@GET
public Call<User> getJSON(@Url String string, @Header("Authorization") String myAuthString);

然后像这样称呼它:

Call<User> call = service.getJSON("https://api.url.com/", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");

QWxhZGRpbjpvcGVuIHNlc2FtZQ==替换为Base64编码的username:password字符串。

如果您需要为每个API调用传递用户名和密码,并希望保持方法签名清洁,那么最好使用自定义OkHttpInterceptor方法。