使用Cookie Jar在React Native Activity和Native Android Activity之间共享cookie

3

我正在构建一个需要使用本地Android活动和React Native Android活动的应用程序。我使用Cookie向服务器请求授权并在Android活动中获取资源。我也希望在我的React Native Activity中使用这些相同的Cookie。

在我的Android活动中,我使用OkHTTP3客户端进行请求处理和Cookie存储。该库具有有用的CookieJar类,可处理存储和发送Cookie。

在我的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());
            }
        });
    }
}
1个回答

2

解决方案就是简单地使用由React Native NetworkingModule创建的OkHTTP客户端。该客户端在应用程序中持续存在,并拥有自己的CookieJar。在JavaScript中使用fetch会使用此客户端,并能够获取和设置cookie。如果我们在本地Java代码中使用相同的客户端实例来发出请求,那么一切都能完美工作。

mHttpClient = new AuthClient(OkHttpClientProvider.getOkHttpClient());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接