Authorization headers with Retrofit + Robospice + Jackson

940 views Asked by At

I am creating app that consumes REST Api. My API has ability to login/logout in order to access private data. I am creating consumer(client Android app) with Retrofit + Robospice + Jackson.
Everything was okey, but than authorization part came into play.
I need to provide token and other credentials in my request Authorization Header.
This can be easily done by using RequestInterceptor. Here is complete tutorial how to use basic Authentication.
Basic Authentication with Retrofit .
It is clear how to implement this. But in my case I also have resources that can be accessed without credentials.

Here is part of my API declared with Retrofit Annotations

public interface MalibuRestApi {
    //Doesn't need credentials
    @GET("/store/categories")
    Category.List categoryList();
    //Doesn't need credentials
    @GET("/store/categories/{id}/products")
    Product.List productList(@Path("id")int categoryId);
    // Needs credentials
    @POST("/store/users/{id}/logout")
       // Needs credentials
    User logout(@Path("id") int id,@Body Credentials userCredentials);
       // Needs credentials !!!!!!!!!!!!!!!!!!!!
    @POST("/store/users/{id}/orders/")
    void makeAnOrder(@Path("id") int userId,@Body Order order,Callback<Void> callback);


}

Please have a look on makeAnOrder method. It uses POST body to pass details about order. So combining credentials and order seems horrible and not efficient, and I won't use it under no circumstances.

It is possible to use interceptor.

  builder.setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade request) {
                    if 
                    String token = .... // getting token.
                    request.addHeader("Accept", "application/json");
                    request.addHeader("Authorization",token);
                }
            });

I can filter requests and add Auth headers where I need them according to request URL, but ......
According to the discussion here. @JakeWharton

The relative URL is not exposed in the request interceptor because it may not be fully resolved yet. A request interceptor has the ability to perform path replacements and append query parameter

There is one possible workaround.
@powerje

I'm not sure how to access the relative URL in RequestInterceptor but the solution I used in a similar situation was to check my UserManager (a global which manages the currently logged in user) to see if a user is logged in, if they are I add the auth header, otherwise I don't.

I have already similar class Session manager that is created in custom Application class, so I assume that it will live until application(linux dalvik/art process) is destroyed.
So it is possible to do something like this.

builder.setRequestInterceptor(new RequestInterceptor() {
                    @Override
                    public void intercept(RequestFacade request) {
                        sessionManager =(SessionProvider) getApplicationContext().getSessionManager();
                        if(sessionManager.userLoggedIn) {
                        String token = .... // getting token.
                        request.addHeader("Accept", "application/json");
                        request.addHeader("Authorization",token);
                        }
                    }

I haven't tested this yet, but it pretends to work.
In this case redundant headers are passed to public resource requests, that don't really require them.

So maybe this can be a sort of solution not a question, but I really need some advice about any other ways (maybe not better) to solve this problem.

I will be grateful for any help.

0

There are 0 answers