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.
Answer from Mahendra Pratap on Stack Overflow
» npm install @react-native-cookies/cookies
» npm install @react-native-community/cookies
Hello,
I want to render a WebView within the app, but before loading it I would like to set cookies.
Would can one do this in React Native, using Expo? Thanks!
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.
June 2024 Update:
Tested with the following versions:
"dependencies": {
"react": "18.2.0",
"react-native": "0.73.4",
"react-native-webview": "^13.7.1"
}
The injected JS code to trigger the message event has changed to
window.ReactNativeWebView.postMessage(document.cookie)
And here's a working example:
import React from "react";
import { View, StyleSheet } from "react-native";
import WebView from "react-native-webview";
const App = () => {
const onMessage = (event: any) => {
const { data } = event.nativeEvent;
const cookies: string[] = data?.split(";");
// Here you have access to cookies, e.g. foo=bar
console.log(cookies);
};
// Here I needed to have updated cookie values every 3s
// so I used an interval to post the data to RN layer
const JSCode = `
setInterval(() => {
window.ReactNativeWebView.postMessage(document.cookie)
}, 3000);
window.addEventListener("beforeunload", function() {
for (var i = 0; i < setInterval.length; i++) {
clearInterval(i);
}
});
`;
return (
<View style={StyleSheet.absoluteFill}>
<WebView
source={{
uri: "...",
}}
injectedJavaScript={JSCode}
onMessage={onMessage}
useWebView2
/>
</View>
);
};
export default App;
Solved by using this: https://github.com/react-native-community/react-native-cookies
CookieManager.clearAll();
I used incognito mode as a turnaround and it worked perfect for me.
<WebView
incognito={true}
userAgent="Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko"
source={{
uri:
'your url',
}}
style={{ flex: 1 }}
/>
In react native webview cookies are default enable please check following link https://facebook.github.io/react-native/docs/webview.html
thirdPartyCookiesEnabled?: bool
Boolean value to enable third party cookies in the WebView.
Used on Android Lollipop and above only as third party cookies are enabled by
default on Android Kitkat and below and on iOS. The default value is true.
<WebView
source={{uri: 'https://github.com/facebook/react-native'}}
style={{marginTop: 20}}
thirdPartyCookiesEnabled : true
/>
Use property sharedCookiesEnabled={true} in webView. Its working in myCase