【问题标题】:Android Picasso library, How to add authentication headers?Android Picasso 库,如何添加身份验证标头?
【发布时间】:2014-08-08 01:18:21
【问题描述】:

我尝试使用自定义身份验证器设置自定义 OkHttpClient,但是正如文档所说:“响应来自远程 Web 或代理服务器的身份验证挑战。”我必须对每张图片提出 2 个请求,这并不理想。

有没有像 Retrofit 这样的请求拦截器?还是我在 OkHttpClient 中遗漏了什么?

我使用的是最新版本:

compile 'com.squareup.picasso:picasso:2.3.2'
compile 'com.squareup.okhttp:okhttp:2.0.+'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.+'
compile 'com.squareup.okio:okio:1.0.0'

谢谢!

【问题讨论】:

    标签: android picasso okhttp


    【解决方案1】:

    由于 Picasso 2.5.0 OkHttpDownloader 类已更改,假设您使用的是 OkHttp3(以及 picasso2-okhttp3-downloader),因此您必须执行以下操作:

    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request newRequest = chain.request().newBuilder()
                            .addHeader("X-TOKEN", "VAL")
                            .build();
                    return chain.proceed(newRequest);
                }
            })
            .build();
    
    Picasso picasso = new Picasso.Builder(context)
            .downloader(new OkHttp3Downloader(client))
            .build();
    

    来源:https://github.com/square/picasso/issues/900

    【讨论】:

    • 在第一行中,您在 'OkHttpClient();' 之前错过了 'new'
    • 请注意,最新的okhttpclient版本为3,与毕加索2不兼容。如果你想使用这个解决方案,你需要okhttpclient 2。
    • networkInterceptors是OkHttp3中的不可变列表,不能直接添加,需要使用builder。 OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); builder.networkInterceptors().add(...) ; client = builder.build().
    • 可以从github.com/JakeWharton/picasso2-okhttp3-downloader获取OkHttp3Downloader
    • 另外请注意,当你使用新的毕加索实例时,不要使用 .with(context),因为这会撤消自定义拦截器。
    【解决方案2】:

    请参阅bryant1410's answer 了解更新的解决方案。


    这样的事情可以完成设置 API-key 标头的工作:

    public class CustomPicasso {
    
        private static Picasso sPicasso;
    
        private CustomPicasso() {
        }
    
        public static Picasso getImageLoader(final Context context) {
            if (sPicasso == null) {
                Picasso.Builder builder = new Picasso.Builder(context);
                builder.downloader(new CustomOkHttpDownloader());
                sPicasso = builder.build();
            }
            return sPicasso;
        }
    
        private static class CustomOkHttpDownloader extends OkHttpDownloader {
    
            @Override
            protected HttpURLConnection openConnection(final Uri uri) throws IOException {
                HttpURLConnection connection = super.openConnection(uri);
                connection.setRequestProperty(Constants.HEADER_X_API_KEY, "MY_API_KEY");
                return connection;
            }
        }
    }
    

    【讨论】:

    • 明天试试!!谢谢,它看起来是一个非常简洁的解决方案!
    • 你确定这有效吗?我得到 NoSuchMethodError: No static method source(Ljava/io/File;)Lokio/Source; Lokio/Okio 班;或其超类('okio.Okio' 的声明出现在 /system/framework/okhttp.jar 中)。
    • 抱歉回复晚了,但您的解决方案效果很好!谢谢!
    • 不起作用,因为方法 openConnection 不能再被覆盖... :/
    • @martyonair 这就是为什么我特别提到bryant1410's answer
    【解决方案3】:

    您还可以按照documentation of OkHttp 中的建议添加身份验证

    只需添加此客户端

    final OkHttpClient client = new OkHttpClient.Builder()
                    .authenticator(new Authenticator() {
                        @Override
                        public Request authenticate(Route route, Response response) throws IOException {
                            String credential = okhttp3.Credentials.basic("user", "pw");
                            return response.request().newBuilder()
                                    .header("Authorization", credential)
                                    .build();
                        }
                    })
                    .build();
    

    这样对毕加索:

    final Picasso picasso = new Picasso.Builder(this)
                    .downloader(new OkHttp3Downloader(client))
                    .build();
    Picasso.setSingletonInstance(picasso);
    

    唯一需要的依赖是:

    compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2'
    

    【讨论】:

    • 这个有效,但我在服务器日志上注意到的唯一问题是,当我请求下载图像时,首先尝试不使用身份验证标头,然后在服务器返回 401 后,它会使用我的身份验证器重复调用。在应用程序端日志看起来都不错。当我切换到 Interceptor 而不是 Authenticator 时,我不再在服务器日志中看到 401。
    【解决方案4】:

    它正在工作

            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                               .authenticator(new Authenticator()
                               {
                                   @Override
                                   public Request authenticate(Route route, Response response) throws IOException
                                   {
                                       String credential =  Credentials.basic("username","password");
                                       return response.request().newBuilder()
                                               .header("Authorization", credential)
                                               .build();
                                   }
                               }).build();
    
                       Picasso picasso = new Picasso.Builder(OnDemandImageCaptureActivity.this)
                               .downloader(new OkHttp3Downloader(okHttpClient))
                               .build();
                            picasso.load("http://example.com/abc.jpeg").into(ivcamera);
    

    依赖:

    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
    

    【讨论】:

      【解决方案5】:

      这样的简单方法将保留默认的 OkHttpClient 超时和缓存配置:

      private class MyOkHttpDownloader extends OkHttpDownloader {
      
          public MyOkHttpDownloader(final Context context) {
              super(context);
              getClient().interceptors().add(new Interceptor() {
                  @Override
                  public Response intercept(Chain chain) throws IOException {
                      Request newRequest = chain.request().newBuilder()
                              .addHeader("X-TOKEN", "VAL")
                              .build();
                      return chain.proceed(newRequest);
                  }
              });
          }
      }
      
      Picasso picasso = new Picasso.Builder(context).downloader(new MyOkHttpDownloader(context)).build();
      

      【讨论】:

      • .interceptors() 不公开
      猜你喜欢
      • 2014-11-25
      • 2014-06-02
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      相关资源
      最近更新 更多