How can get cookie which is set in webview in react-native?

Subhendu Kundu picture Subhendu Kundu · Jun 6, 2019 · Viewed 10.8k times · Source

I am trying to retrieve user entered zipcode which is added to the cookie in the webview. How do I get it? I have tried react-native-cookies which is getting an empty object.

import CookieManager from 'react-native-cookies';

componentWillMount() {
    CookieManager.get('https://www.example.com')
    .then((res) => {
      console.log('CookieManager.get from webkit-view =>', res);
    });
  }
}

<WebView
  style={styles.webview}
  source={{ uri: 'https://www.example.com' }}
  injectedJavaScript={INJECTED_JAVASCRIPT}
  mixedContentMode="compatibility"
  javaScriptEnabled
  domStorageEnabled
  thirdPartyCookiesEnabled
  sharedCookiesEnabled
  originWhitelist={['*']}
  useWebKit
/>

I am trying out in iOS simulator. Android works great. I see https://github.com/react-native-community/react-native-webview/pull/175 as merged but can't figure out how to use it to get the user set cookies.

Answer

Mahendra Pratap picture Mahendra Pratap · Jun 20, 2019

You can try the following trick without using any native modules. just go through the Code or URL.

// @flow

import React, { Component } from 'react';
import {
  WebView,
} from 'react-native';

class LoginScreen extends Component {
  state = {
    cookies    : {},
    webViewUrl : ''
  }

  onNavigationStateChange = (webViewState: { url: string }) => {
    const { url } = webViewState;

    // when WebView.onMessage called, there is not-http(s) url
    if(url.includes('http')) {
      this.setState({ webViewUrl: url })
    }
  }

  _checkNeededCookies = () => {
    const { cookies, webViewUrl } = this.state;

    if (webViewUrl === 'SUCCESS_URL') {
      if (cookies['cookie-name-for-jwt']) {
        alert(cookies['cookie-name-for-jwt']);
        // do your magic...
      }
    }
  }

  _onMessage = (event) => {
    const { data } = event.nativeEvent;
    const cookies  = data.split(';'); // `csrftoken=...; rur=...; mid=...; somethingelse=...`

    cookies.forEach((cookie) => {
      const c = cookie.trim().split('=');

      const new_cookies = this.state.cookies;
      new_cookies[c[0]] = c[1];

      this.setState({ cookies: new_cookies });
    });

    this._checkNeededCookies();
  }

  render() {
    const jsCode = "window.postMessage(document.cookie)"
    // let jsCode = "window.postMessage(document.cookie= 'login=; expires=Bla bla bla')"; // if you need to write some cookies, not sure if it goes to shared cookies, most probably no :)

    return (
      <WebView
        source={{ uri: 'AUTH_URL' }}
        onNavigationStateChange={this.onNavigationStateChange}
        onMessage={this._onMessage}
        injectedJavaScript={jsCode}
        style={{ flex: 1 }}
      />
    );
  }
}

export default LoginScreen;

https://gist.github.com/kanzitelli/e5d198e96f81b7a8263745043766127c

Hope this work for you.