Authentication Apollo Graphql for android

Viewed 1611

I'm developing an android application that uses GraphQL as the back-end. I have the query and mutation part working perfectly. But I couln't find any documentations for authentication.

So how can I pass the username and password to the server and authenticate it?

LocalApolloClient.java :

public class LocalApolloClient {
    private static final String URL = "http://192.168.1.100/graphql/";
    private static ApolloClient apolloClient;
    private static String authHeader = "";


    public static ApolloClient getApolloClient(){
        //HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        //loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(chain -> {
                    Request original = chain.request();
                    Request.Builder builder = original.newBuilder().method(original.method(), original.body());
                    builder.header("Authorization", authHeader);
                    return chain.proceed(builder.build());
                })
                .build();

        apolloClient = ApolloClient.builder()
                .serverUrl(URL)
                .okHttpClient(okHttpClient)
                .build();

        return apolloClient;
    }
}

Please note :

  • This is not a duplicate question
  • There is no proper documentation for graphQl

So kindly Justify if you negative vote.

3 Answers

You need to set the header on ApolloClient, not on the OkHttpClient. Something like this:

ApolloClient.builder()
            .serverUrl(context.getString(R.string.graphql_base_url))
            .addApplicationInterceptor(object: ApolloInterceptor {
                override fun interceptAsync(
                    request: ApolloInterceptor.InterceptorRequest,
                    chain: ApolloInterceptorChain,
                    dispatcher: Executor,
                    callBack: ApolloInterceptor.CallBack
                ) {
                    val newRequest = request.toBuilder().requestHeaders(RequestHeaders.builder().addHeader("Authorization", "Basic ...").build()).build()
                    chain.proceedAsync(newRequest, dispatcher, callBack)
                }

                override fun dispose() {
                }
            }).build()

If you want to authenticate with username and password, you have to base64 encode username and password and pass it to the variable authHeader. For example, for the username Aladdin and password OpenSesame you get this:

private static String authHeader = "Basic QWxhZGRpbjpPcGVuU2VzYW1l";

See: https://en.wikipedia.org/wiki/Basic_access_authentication

Try this

  1. The HTTP server can be set up as HTTPS server
  2. The server also has username/password database (passwords might be saved with bcrypt)
  3. The client opens the HTTPS connection, it authenticates the server (so a server certificate is needed) and after exchanging the master key, the connection should be encrypted.
  4. The client sends the username/password in clear to the server
  5. The server runs bcrypt on the password and compares it with the one stored in the database

If you have any concern refer this original post.

NB:I personally never tried this.

Related