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());
}
});
}
}
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With