-1

I have a webapp that's already production ready to run inside a React Native Webview. The app uses the package js-cookie which saves the accessToken and refreshToken to the browser cookies.

import Cookies from 'js-cookie';
import { LoginTokens } from '@/types/auth';

export const saveTokensToCookies = (loginTokens: LoginTokens) => {
    ...
    Cookies.set('accessToken', loginTokens.accessToken, {
        expires: expiresAt,
    });
}

export const getTokenFromCookies = (token: string): string | undefined => {
  if (token === TokenTypes.ACCESS_TOKEN) {
    return Cookies.get(TokenTypes.ACCESS_TOKEN);
  }

  if (token === TokenTypes.REFRESH_TOKEN) {
    return Cookies.get(TokenTypes.REFRESH_TOKEN);
  }
  return undefined;
};

If I log the value from getTokenFromCookies from my react app it works without any issues.

However when I try to access these values from the webview, it doesnt seem to be saved to the browser cookies. Though I do understand that webview is not ran inside a browser, I would like to know any alternate ways on how to approach this? I need to be able to at least log-in on my react app from my webview but since it relies on browser cookies it presents a challenge. Below is how I am able to check cookies from my react native app.

const CHECK_COOKIE: string = `
    ReactNativeWebView.postMessage("Cookie: " + document.cookie);
    true;
`;

const onNavigationStateChange = (navigationState: WebViewNavigation) => {
    if (webviewRef.current) {
        webviewRef.current.injectJavaScript(CHECK_COOKIE);
    } else {
        console.log('no webview');
    }
};

const onMessage = (event) => {
    const { data } = event.nativeEvent;

    console.log(data);
};

return (
    <View className="absolute inset-0 z-10 bg-white pt-14">
        <Menu canGoBack onBack={handleLogout} />
            <SafeAreaView style={{ flex: 1 }}>
                <WebView
                  ref={webviewRef}
                  source={{ uri: accessUrl }}
                  onNavigationStateChange={onNavigationStateChange}
                  onMessage={onMessage}
                  originWhitelist={['*']}
                  sharedCookiesEnabled
                  thirdPartyCookiesEnabled
                  javaScriptEnabled
                />
            </SafeAreaView>
        </Menu>
    </View>
)

After logging in I dont see the accessToken and refreshToken.

How am I able to log in from inside my webview? Any suggestions?

2
  • is the url starts with http or you are loading local file:// url? Commented Nov 14 at 3:58
  • the url starts with http Commented Nov 14 at 5:37

1 Answer 1

0

Why document.cookie is “empty” in WebView

A few important points:

  1. Separate cookie jars

    • Chrome/Safari on the device have one cookie store.

    • react-native-webview uses its own cookie store. They do not magically share cookies.

    • So if you log in in the device browser, the WebView won’t see those cookies.

  2. Even inside WebView, cookies may be blocked or dropped
    On Android especially, there are long-standing issues where:

    • document.cookie access can be denied in some situations (mixed content, http vs https, etc.).

    • Cookies with Secure, SameSite=None, or mismatched domain/path attributes simply never get stored.

  3. Your check is running from React Native, but executes inside the WebView
    Your CHECK_COOKIE string is correct in that it runs in page context, but it will only show cookies stored for that origin in the WebView’s own jar. It will not show:

    • Cookies from the system browser, or

    • HttpOnly cookies (they never appear in document.cookie), or

    • Cookies never stored because of security attributes.

So, if:

  • The user logged in in the normal browser, and

  • You then open the same URL in WebView,

you will not see those cookies. The web app inside WebView must perform its own login flow, or you must manually inject tokens.

What you can actually do

You have three realistic approaches, depending on how much you can modify the web app.

Option 1 - Inject tokens into cookies from React Native

If you already have tokens in React Native (e.g., from a native login flow or SecureStore), you can inject them into the WebView as cookies so the React app (with js-cookie) just works.

React Native:

const injectTokens = (accessToken: string, refreshToken: string) => `
  (function() {
    // Adjust domain/path as needed
    document.cookie = "accessToken=${accessToken}; path=/";
    document.cookie = "refreshToken=${refreshToken}; path=/";
  })();
  true;
`;

<WebView
  ref={webviewRef}
  source={{ uri: accessUrl }}
  onLoadEnd={() => {
    if (webviewRef.current && accessToken && refreshToken) {
      webviewRef.current.injectJavaScript(
        injectTokens(accessToken, refreshToken)
      );
    }
  }}
  sharedCookiesEnabled
  thirdPartyCookiesEnabled
  javaScriptEnabled
/>

Now inside the web app, your existing js-cookie calls should work exactly as in the browser.

Option 2 - Let the web app send tokens out to React Native

If the login happens inside the web app running in WebView, add code in the React app to post the tokens via the WebView bridge:

// In your React web app, where you already have loginTokens
import Cookies from 'js-cookie';

export const saveTokensToCookies = (loginTokens: LoginTokens) => {
  Cookies.set('accessToken', loginTokens.accessToken, { expires: expiresAt });
  Cookies.set('refreshToken', loginTokens.refreshToken, { expires: expiresAt });

  // If running inside React Native WebView, also send them out:
  if ((window as any).ReactNativeWebView) {
    (window as any).ReactNativeWebView.postMessage(
      JSON.stringify({
        type: 'AUTH_TOKENS',
        accessToken: loginTokens.accessToken,
        refreshToken: loginTokens.refreshToken,
      }),
    );
  }
};

Then in React Native:

const onMessage = (event) => {
  try {
    const data = JSON.parse(event.nativeEvent.data);

    if (data.type === 'AUTH_TOKENS') {
      const { accessToken, refreshToken } = data;
      // store in SecureStore/AsyncStorage and use in native API calls
    } else {
      console.log('WebView message:', data);
    }
  } catch {
    console.log('Raw WebView message:', event.nativeEvent.data);
  }
};

This way your native side has the same auth context as the web app, without relying on document.cookie at all.

Option 3 - Stop using cookies for tokens inside the web app

Since you control the React web app, consider abstracting token storage:

// tokenStorage.ts (web)
const TOKEN_KEYS = {
  access: 'accessToken',
  refresh: 'refreshToken',
};

export const setTokens = (tokens: LoginTokens) => {
  localStorage.setItem(TOKEN_KEYS.access, tokens.accessToken);
  localStorage.setItem(TOKEN_KEYS.refresh, tokens.refreshToken);
};

export const getTokens = (): LoginTokens | null => {
  const accessToken = localStorage.getItem(TOKEN_KEYS.access);
  const refreshToken = localStorage.getItem(TOKEN_KEYS.refresh);
  if (!accessToken || !refreshToken) return null;
  return { accessToken, refreshToken };
};

Then, from React Native, you can use the WebView bridge:

const GET_TOKENS = `
  (function() {
    try {
      var tokens = window.localStorage.getItem('accessToken') 
        ? {
            accessToken: window.localStorage.getItem('accessToken'),
            refreshToken: window.localStorage.getItem('refreshToken'),
          }
        : null;
      window.ReactNativeWebView.postMessage(JSON.stringify({
        type: 'TOKENS_FROM_WEB',
        tokens: tokens,
      }));
    } catch (e) {
      window.ReactNativeWebView.postMessage(JSON.stringify({
        type: 'TOKENS_ERROR',
        error: e && e.message,
      }));
    }
  })();
  true;
`;

domStorageEnabled is on by default, but you can be explicit:

<WebView
  domStorageEnabled
  javaScriptEnabled
  ...
/>
Sign up to request clarification or add additional context in comments.

2 Comments

This is the best answer! Eventually I was able to figure out the solution and we did exactly the same thing by having my webapp send the cookies to React Native if it's loaded via webview the exact same way you did. Then received it on my onMessage I manually set document.cookies there.
Please note that Generative AI (e.g., ChatGPT) is banned and read Help Center: AI policy. It is not permitted to use AI tools to generate or reword content that you post on Stack Overflow.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.