Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPS request does not send the Authorization header while HTTP request sends it without any problem #1037

Closed
sam-ghosh opened this issue Aug 28, 2015 · 6 comments

Comments

@sam-ghosh
Copy link

I am having a problem with accessing HTTPS urls with Retrofit. I am passing a custom header in the following format

Authorization = Token 121231ASDFSDF

This gets passed in the Retrofit network call when the App.BASE_URL is http://app.mydomain.com but when App.BASE_URL = https://app.mydomain.com this authorization header is not being passed and my backend gives an error

retrofit client

public class EMRestClient {

    private static EMRestInterface mEMRestService;


    public static EMRestInterface getmEMRestService() {

        if (mEMRestService == null) {
            Gson gson = new GsonBuilder()
                    .setExclusionStrategies(new ExclusionStrategy() {
                        @Override
                        public boolean shouldSkipField(FieldAttributes f) {
                            return f.getDeclaringClass().equals(RealmObject.class);
                        }

                        @Override
                        public boolean shouldSkipClass(Class<?> clazz) {
                            return false;
                        }
                    })

                    .registerTypeAdapter(Date.class, new DateSerializer())
                    //.setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)    // converts 'short_description' in JSON to shortDescription, java style
                    .create();


            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint(App.BASE_URL)                // sets base url
                    .setRequestInterceptor(new AuthTokenHeaderInterceptor())        // provides Authorization : Token XYZ header if required
                    .setLogLevel(RestAdapter.LogLevel.FULL)                         // logs all input and output request/response for debug
                    .setConverter(new GsonConverter(gson))                          // provides additional conversion functions from json if reqd
                    .build();

            mEMRestService = restAdapter.create(EMRestInterface.class);
        }

        return mEMRestService;
    }

    public interface EMRestInterface {
     // definitions of API endpoints

    }
}

request interceptor

public class AuthTokenHeaderInterceptor implements RequestInterceptor {
    @Override
    public void intercept(RequestFacade request) {


        request.addHeader("Screen-Width", String.valueOf(App.SCREEN_WIDTH));
        request.addHeader("Screen-Height", String.valueOf(App.SCREEN_HEIGHT));
        request.addHeader("Screen-Density", String.valueOf(App.SCREEN_DENSITY));
        request.addHeader("Screen-Scaled-Density", String.valueOf(App.SCREEN_SCALED_DENSITY));
        request.addHeader("Screen-Density-DPI", String.valueOf(App.SCREEN_DENSITY_DPI));
        request.addHeader("Device-Type", App.DEVICE_TYPE);
        request.addHeader("App-Version", App.APP_VERSION_NAME);
        request.addHeader("App-Version-Code", String.valueOf(App.APP_VERSION_CODE));

        if (App.getLoginData()!=null) {
            String authToken = App.getLoginData().getAuthToken();
            if (!authToken.equals("")) {
                String authTokenString = "Token " + authToken;
                request.addHeader("Authorization", authTokenString);
            }
        }


    }
}
@caseykulm
Copy link

Have you verified that when you use https that the line,

request.addHeader("Authorization", authTokenString);

, is reached?

@JakeWharton
Copy link
Member

Is OkHttp included in your app? Is the endpoint redirecting you across hosts? OkHttp strips headers across host redirects for safety purposes.

@shahzaibmuneeb
Copy link

Hi Jake. I work with the Som (OP) and have been debugging this issue.

It seems like when the word "Authorization" is sent in the header it is not passed as the other headers are. However, when I change this word to anything else (e.g. customAuth) it is sent as per usual. So my suspicion is that Authorization is some kind of keyword which when used via HTTPS, goes missing?

"customAuth" is the exact same data that is in "Authorization" and it's behaviour does not change when I change to HTTPS.

(I'm using Fiddler to intercept my packets.)

Screenshots of intercepted headers:

Http:
http

Https:
https

Do you have any more information on this behaviour? Is it expected? unexpected?

Thank you :)

@JakeWharton
Copy link
Member

OkHttp strips the "Authorization" header when redirected across hosts (connections) via a 3xx response from the original host.

@shahzaibmuneeb
Copy link

So after revisiting the issue, we worked out you were entirely correct about it being a redirect issue.

For those interested: We are using Django as our backend and by default when you do not provide a trailing slash on the endpoint Django redirects from the non-slash endpoint to the slash endpoint.

You can turn this behaviour off if you do not want to append slash's to your endpoints.

For more information: https://docs.djangoproject.com/en/dev/ref/settings/#append-slash

Thanks for your help Jake.

@JakeWharton
Copy link
Member

Great! Glad it's resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants