Android Picasso Authorization header not working - android

I'am trying to addHeader to the Picasso request, so I've searched and followed what suggested to do, in this case adding an interceptor.But it's not working and not giving any error.
new Picasso.Builder(mContext).downloader(RestAsyncHttpClient.getOkHttpDownloader(header)).build()
.load("https://myUrl.jpg").into(mMediaImageView);
And my okhttpDownload:
public static OkHttpDownloader getOkHttpDownloader(final HashMap<String, String> headers) {
OkHttpClient okHttpClient = mHttpClient.clone();
okHttpClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Builder builder = chain.request().newBuilder();
if (!headers.isEmpty())
for (Entry<String, String> entry : headers.entrySet())
builder.addHeader(entry.getValue(), entry.getKey());
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
});
return new OkHttpDownloader(okHttpClient);
}
I've copied the header and the request and tried in postMan app and everything worked, I've also implemented OnImageLoadFailed but it's not triggered so i can't understand.
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
String test = "sad";
}

The problem wasn't Picasso or OkHhtp everything is at it should, but the problem was i made a mistake adding the header i was putting "MY TOKEN" "Authorization" instead of "Authorization" "MY TOKEN. i will not delete the post because it contains a snippet of "how to add an header to Picasso"

Related

retrofit , okhttp3 add header

I need to get the XML file from the site. I'm learning to use Retrofit.
I need to make a request and attach my API key via the "X-AppId" header. It should look like this:
X-AppId: my key.
If I do this from the browser, I get the answer.
Through the retrofit I get the access
error 403 Forbidden code = 403, message = Forbidden, url = https: //
Tell me how it is implemented properly to receive an answer from the server code = 200
Here is my implementation:
public interface myAPIinterface {
#GET("/api/ru/index/route/?from=Minsk&to=Warsaw")
Call<Routes> getProducts();
}
This is the activity where I output to the log:
private void getProducts(){
final ProgressDialog loading = ProgressDialog.show(this,"Fetching Data","Please wait...",false,false);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Log.d(TAG, "getProducts");
httpClient.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader("X-AppId:", "97377f7b702d7198e47a2bf12eec74")
.build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://rasp.rw.by")
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
myAPIinterface api = retrofit.create(myAPIinterface.class);
Call<Routes> call = api.getProducts();
call.enqueue(new Callback<Routes>() {
#Override
public void onResponse(#NonNull Call<Routes> call, #NonNull Response<Routes> response) {
Log.d(TAG, "onResponse");
Log.d(TAG, String.valueOf(kk));
Log.d(TAG, String.valueOf(response));
loading.dismiss();}
#Override
public void onFailure(Call<Routes> call, Throwable throwable) {
loading.dismiss();
Log.d(TAG, "onFailure" + throwable);
}
});
this is a log:
Response{protocol=http/1.1, code=403, message=Forbidden,
url=https://rasp.rw.by/api/ru/index/route/?from=Minsk&to=Warsaw}
if I take third-party sites where there are no headers, I get a response of 200 without problems. What am I doing wrong in this case? Thank you.
Oh, man, what are you doing. You can use annotations like #Query, #Header, etc.
public interface myAPIinterface {
#GET("/api/ru/index/route")
Call<Routes> getProducts(#Header("X-AppId:") String YOUR_APP_ID,
#Query("from") String from,
#Query("to") String to)
}
Then you can create request like this:
Retrofit retrofit = new Retrofit.Builder().
.baseUrl("https://rasp.rw.by")
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
retrofit.create(myAPIinterface.class).getProducts(myId, "Minsk", "Warsaw").enqueue ...
How It can help? You forgot to add header at second retrofit and then you have 403 error. So, You must add annotations, and this will be the last mistake when you forgot to put value to header/query/etc.

Adding fields to URL using Retrofit

I am building an Android APP where I use the Internet Game Database API through Mashape market place. I am using Retrofit for the get requests and getting data from the API requires an API key.
I got it to work but the API only return game ids and I want the game names and other information, but I am not sure how to add the fields. This is how Mashape query it:
HttpResponse<String> response = Unirest.get("https://igdbcom-internet-game-database-v1.p.mashape.com/games/?fields=name%2Crelease_dates")
.header("X-Mashape-Key", "API KEY HERE")
.header("Accept", "application/json")
.asString();
and this is my Retrofit Interface
public interface GamesAPIService {
#GET("/games/")
Call<List<GamesResponse>> gameList(#Query("mashape-key") String apikey);
}
I tried to use this
#GET("/games/?fields=name,release_dates")
But no luck, I also tried with #Field but didn't work either. Any ideas? Thanks.
Edit: Just to clarify when I add the "?fields=name,release_dates" I get 401 Unauthorized Error.
Firstly I think you need to add mashape key to all your request.
OkHttpClient httpClient = new OkHttpClient();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("X-Mashape-Key", "API_KEY_HERE")
.addHeader("Accept", "application/json")
.build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://igdbcom-internet-game-database-v1.p.mashape.com")
.client(httpClient)
.build();
And then this is information query.
public interface GamesAPIService {
#GET("/games")
Call<List<GamesResponse>> gameList(#Query("fields") String value);
}
And last thing for calling.
GamesAPIService gamesAPIService = retrofit.create(GamesAPIService.class);
Call<List<GamesResponse>> call = gamesAPIService.gameList("name,release_dates");
if (call!=null){
call.enqueue(new Callback<List<GamesResponse>>() {
#Override
public void onResponse(Call<List<GamesResponse>> call, Response<List<GamesResponse>> response) {
// handle success
}
#Override
public void onFailure(Throwable t) {
// handle failure
}
});
}

how to contain header when I redirect in retrofit

I tried to make oauth2 for android application. it has little bug.
My bug is It doesn't have header like Authorization when I redirect
MyCookieCode. It send Authorization when I was login. but It doesn't work when I redirect
public static Retrofit getLoginRetrofitOnAuthz() {
Retrofit.Builder builder = new Retrofit.Builder().baseUrl(ServerValue.AuthServerUrl).addConverterFactory(GsonConverterFactory.create());
if (LoginRetrofitAuthz == null) {
httpClientAuthz.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
String str = etUsername.getText().toString() + ":" + etPassword.getText().toString();
String Base64Str = "Basic " + Base64.encodeToString(str.getBytes(), Base64.NO_WRAP);
System.out.println(Base64Str);
Request request = chain.request().newBuilder().addHeader("Authorization", Base64Str).build();
return chain.proceed(request);
}
});
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
httpClientAuthz.cookieJar(new JavaNetCookieJar(cookieManager));
LoginRetrofitAuthz = builder.client(httpClientAuthz.build()).build();
}
return LoginRetrofitAuthz;
}
Server Result (Top-Login, Bottom, Redirect)
Do you know how to staying header on redirect ?
in fact the sinner is OkHttp, but not Retrofit.
OkHttp removes all authentication headers on purpose:
https://github.com/square/okhttp/blob/7cf6363662c7793c7694c8da0641be0508e04241/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
// When redirecting across hosts, drop all authentication headers. This
// is potentially annoying to the application layer since they have no
// way to retain them.
if (!sameConnection(url)) {
requestBuilder.removeHeader("Authorization");
}
Here is the discussion of this issue: https://github.com/square/retrofit/issues/977
You could use the OkHttp authenticator. It will get called if there is a 401 error returned. So you could use it to re-authenticate the request.
httpClient.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
return response.request().newBuilder()
.header("Authorization", "Token " + DataManager.getInstance().getPreferencesManager().getAuthToken())
.build();
}
});
However in my case server returned 403 Forbidden instead of 401. And I had to get
response.headers().get("Location");
in-place and create and fire another network request:
public Call<Response> getMoreBills(#Header("Authorization") String authorization, #Url String nextPage)

How to get headers from all responses using retrofit

I'm using Retrofit library version 2 with OkHttpClient.
I want to get some header from all responses.
I found one solution with OkClient:
public class InterceptingOkClient extends OkClient{
public InterceptingOkClient()
{
}
public InterceptingOkClient(OkHttpClient client)
{
super(client);
}
#Override
public Response execute(Request request) throws IOException
{
Response response = super.execute(request);
for (Header header : response.getHeaders())
{
// do something with header
}
return response;
}
}
But how i can do this if i'm using OkHttpClient?
Yes, this is old question.. but still found to answer because myself too was searching similar one.
okHttpClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Authorization", "auth-value"); // <-- this is the important line, to add new header - replaces value with same header name.
Request request = requestBuilder.build();
Response response = chain.proceed(request);
Headers allHeaders = response.headers();
String headerValue = allHeaders.get("headerName");
return response;
}
});
Hope, this helps!
P.S: no error handled.
You can use the logging interceptor for that. Add it as an interceptor to your OkHttpClient builder while building the client, set the log level and voila! You will have all the information regarding the request as well as the response.
Here's how you can add the interceptor -
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpBuilder.addInterceptor(loggingInterceptor);
client = okHttpBuilder.build();
There are four options when it comes to what you want to Log - NONE,BASIC,HEADERS, and BODY.
Now build the the retrofit instance with the above defined client and you will have all the data you need.

Custom Downloader using Picasso

I have to download an image from a URL which requires some headers ( username,password) along with the request. So i am doing that using the code given here. But calling this function gives the error
java.lang.NoClassDefFoundError: com.squareup.okhttp.OkHttpClient
at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:72)
I am using Picasso 2.3.3 and okhttp-urlconnection-2.0.0-RC2 libraries
The issue has been raised in this post also but changing to 2.3.2 doesnt work.
Do you have OkHttp included in your project? If not, the problem is that you're using the OkHttpDownloader. You can include the OkHttp library in your project or just UrlConnectionDownloader like below.
This was the result I ended up with.
public static Picasso getImageLoader(Context ctx) {
Picasso.Builder builder = new Picasso.Builder(ctx);
builder.downloader(new UrlConnectionDownloader(ctx) {
#Override
protected HttpURLConnection openConnection(Uri uri) throws IOException {
HttpURLConnection connection = super.openConnection(uri);
connection.setRequestProperty("X-HEADER", "VAL");
return connection;
}
});
return builder.build();
}
Since Picasso 2.5.0 OkHttpDownloader class has been changed, so you have to do something like this:
OkHttpClient picassoClient = new OkHttpClient();
picassoClient.networkinterceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("X-HEADER", "VAL")
.build();
return chain.proceed(newRequest);
}
});
new Picasso.Builder(context).downloader(new OkHttpDownloader(picassoClient)).build();
Source: https://github.com/square/picasso/issues/900

Categories

Resources