使用Cookie Jar在React Native Activity和Native Android Activity之间共享Cookie
问题描述:
我正在构建一个需要我使用Native Android活动和React Native Android活动的应用程序。我向服务器发出请求以授权我自己,并使用cookie在我的Android活动中获取资源。我想在我的React Native Activity中使用这些相同的cookie。使用Cookie Jar在React Native Activity和Native Android Activity之间共享Cookie
在我的Android活动中,我使用OkHTTP3客户端发出请求并处理我的Cookie。这个库有一个有用的CookieJar类,可以为我处理存储和发送cookies。
在我的React Native活动中,我使用fetch来提出使用OkHTTP的请求。有没有一种方法让我通过Javascript代码访问我的永久Cookie Jar,这样我就可以在两个活动之间无缝持续的Cookie
我理解一个解决方案是使用桥接并制作自己的Java类,该类包装我的AuthClient一个Javascript可访问的方式,但这个解决方案并不是我想要的。
这个类是Android活动
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();
}
}
});
}
}
这个类是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());
}
});
}
}
答
解决方案就是使用由阵营本地NetworkingModule创建OkHTTP客户端。该客户端通过应用程序持续存在,并拥有自己的CookieJar。在JavaScript中使用提取使用此客户端并能够获取和设置Cookie。如果我们简单地使用这个相同的客户端实例在Native Java代码中发出请求,那么一切都很完美。
mHttpClient = new AuthClient(OkHttpClientProvider.getOkHttpClient());