Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share cookies between React Native Activity and Native Android Activity using Cookie Jar

I'm building an application that requires me to use Native Android Activities and React Native Android Activities. I make requests to a server to Authorize myself and get resources in my Android activity using cookies. I would like to use these same cookies inside of my React Native Activity as well.

In my Android activity I'm using the OkHTTP3 client to make requests and handle my cookies. This library has a useful CookieJar class that handles storing and sending cookies for me.

In my React Native activity i'm using fetch to make requests which uses OkHTTP under the hood. Is there a way for me to access my persistent Cookie Jar through the Javascript code so I have seamless persistence of cookies between both activities

I understand a solution would be to use bridging and make my own Java class that wraps my AuthClient in a Javascript accessible way but this solution is not really what I want.

This class is the Android Activity

public class AndroidActivity extends AppCompatActivity {

    private Button switchToReactButton;
    private Button loginButton;
    private Button getFeedButton;
    private EditText usernameEditText;
    private EditText passwordEditText;
    private OkHttpClient mOkHttpClient;
    private AuthClient mHttpClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_native);
        switchToReactButton = (Button) findViewById(R.id.switchToReactButton);
        getFeedButton = (Button) findViewById(R.id.getFeedButton);
        usernameEditText = (EditText) findViewById(R.id.usernameEditText);
        passwordEditText = (EditText) findViewById(R.id.passwordEditText);
        loginButton = (Button) findViewById(R.id.loginButton);

        mOkHttpClient = new OkHttpClient.Builder()
                .addNetworkInterceptor(new LoggingInterceptor())
                .cookieJar(new MyCookieManager())
                .build();
        mHttpClient = new AuthClient(mOkHttpClient);

        switchToReactButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(AndroidActivity.this, ReactNativeActivity.class);
                startActivity(intent);
            }
        });

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username = usernameEditText.getText().toString();
                String password = passwordEditText.getText().toString();

                try {
                    mHttpClient.doAuth(username, password);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        getFeedButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    mHttpClient.getFeed();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

This class is the AuthClient

public class AuthClient {

    private String username;
    private String password;
    OkHttpClient client;

    public AuthClient(OkHttpClient client)
    {
        this.client = client;
    }

    public void doAuth(String username, String password) throws Exception {
        this.username = username;
        this.password = password;
        Object TAG_CALL = new Object();
        Request getRequest = new Request.Builder()
                .url("https://mywebsite.com/suite/")
                .tag(TAG_CALL)
                .build();
        getAuthCookies(getRequest);
    }

    private void getAuthCookies(Request request) {
        client.newCall(request).enqueue(new Callback() {
            @Override public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                postAuth();
            }
        });
    }

    private void postAuth() throws IOException {
        MediaType JSON = MediaType.parse("application/x-www-form-urlencoded");

        HttpUrl url = HttpUrl.parse("https://mywebsite.com/suite/auth");
        List<Cookie> cookies = client.cookieJar().loadForRequest(url);

        String json = "un="+username+"&pw="+password+"&_spring_security_remember_me=on&X-TOKEN="
                + cookies.get(1).value();

        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(JSON, json))
                .addHeader("Accept", "text/html")
                .addHeader("Accept-Language", "en_US")
                .addHeader("Cookie2", "$Version=1")
                .build();

        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
    }

    public void getFeed() {

        HttpUrl url = HttpUrl.parse("https://mywebsite.com/suite/api/feed/");
        List<Cookie> cookies = client.cookieJar().loadForRequest(url);

        Request getRequest = new Request.Builder()
                .url(url)
                .addHeader("Accept", "application/xml, text/xml, text/html, application/*+xml, application/atom+xml")
                .addHeader("Accept-Language", "en_US")
                .addHeader("Cookie2", "$Version=1")
                .build();

        client.newCall(getRequest).enqueue(new Callback() {
            @Override public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                Log.i("NATIVE", "feed: " + response.body());
            }
        });
    }
}
like image 203
bkapVT Avatar asked Apr 20 '26 09:04

bkapVT


1 Answers

Solution is to simply use the OkHTTP client that is created by React Native NetworkingModule. This client persists through the application and has its own CookieJar. Using fetch in javascript uses this client and is able to get and set cookies. If we simply use this same client instance to make requests in Native Java code everything works perfectly.

mHttpClient = new AuthClient(OkHttpClientProvider.getOkHttpClient());
like image 88
bkapVT Avatar answered Apr 21 '26 21:04

bkapVT