• 7
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

Android Picasso library, How to add authentication headers?

I have tried setting a custom OkHttpClient with a custom Authenticator, however as the doc says: "Responds to authentication challenges from the remote web or proxy server." I have to make 2 requests for each image, and that is not ideal.

Is there a request interceptor like Retrofit does? Or am I missing something in the OkHttpClient?

I'm using the latest versions:

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'

Thanks!

Since Picasso 2.5.0 OkHttpDownloader class has been changed, assuming you are using OkHttp3 (and so picasso2-okhttp3-downloader), so you have to do something like this:

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

Source: https://github.com/square/picasso/issues/900

  • 91
Reply Report

See bryant1410's answer for a more up-to-date solution.


Something like this does the job for setting an API-key header:

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;
        }
    }
}
  • 9
Reply Report
      • 2
    • Are you sure this is working? I get NoSuchMethodError: No static method source(Ljava/io/File;)Lokio/Source; in class Lokio/Okio; or its super classes (declaration of 'okio.Okio' appears in /system/framework/okhttp.jar) when trying this.

You can also add Authentication as suggested in the documentation of OkHttp

Just add this client

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

to Picasso like this:

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

The only dependency needed is:

compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2'
  • 4
Reply Report
    • This one works, but only problem which I notice on server logs is that when I request to download an image, first tries without authentication header and after the server return 401 it repeats the call with my authenticator. On app side logs all looks good. When I switched to Interceptor instead of Authenticator, I don't see 401 on server logs anymore.

It's working

        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);

dependency:

compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
  • 4
Reply Report

A simple way like this will keep default OkHttpClient timeout and cache configurations:

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();
  • 0
Reply Report