I am working on one app, In which I need to keep users last web-session active in react-native-webview
.
Here is a required work-flow.
My app is only have one WebView, Where there is fixed url is loading.
User will open app & login to that website.
When user will kill app & open it again, I need to keep that user logged in as he has already logged in last time.
Here is what i tried so far:
// list cookies (IOS ONLY)
CookieManager.getAll(useWebKit)
.then((res) => {
console.log('CookieManager.getAll from webkit-view =>', res);
});
But as it's suggested, It'll only work in iOS. I am also not able to set that cookies in website that is opened in WebView to keep that session active.
But I didn't found any success yet.
Any suggestion or solution will highly appreciated.
======= Update =======
For Android:
It is working by default, That means we only need to check this for iOS.
actually this problem exist in react-native-webview
Cookies are lost on iOS after application closing
it should be resolve through native code. but today I made a solution and tested with PHP website
import React, {Component} from 'react';
import {StyleSheet, SafeAreaView} from 'react-native';
import {WebView} from 'react-native-webview';
import CookieManager from '@react-native-community/cookies';
import AsyncStorage from '@react-native-community/async-storage';
let domain="http://example.com";
export default class App extends Component {
constructor(props) {
super(props);
this.currentUrl = '';
this.myWebView = React.createRef();
this.state = {
isReady: false,
cookiesString: '',
};
}
jsonCookiesToCookieString = (json) => {
let cookiesString = '';
for (let [key, value] of Object.entries(json)) {
cookiesString += `${key}=${value.value}; `;
}
return cookiesString;
};
componentWillMount() {
this.provideMeSavedCookies()
.then(async (savedCookies) => {
let cookiesString = this.jsonCookiesToCookieString(savedCookies);
const PHPSESSID = await AsyncStorage.getItem('PHPSESSID');
if (PHPSESSID) {
cookiesString += `PHPSESSID=${PHPSESSID};`;
}
this.setState({cookiesString, isReady: true});
})
.catch((e) => {
this.setState({isReady: true});
});
}
onLoadEnd = (syntheticEvent) => {
let successUrl = `${domain}/report.php`;
if (this.currentUrl === successUrl) {
CookieManager.getAll(true).then((res) => {
AsyncStorage.setItem('savedCookies', JSON.stringify(res));
if (res.PHPSESSID) {
AsyncStorage.setItem('PHPSESSID', res.PHPSESSID.value);
}
});
}
};
onNavigationStateChange = (navState) => {
this.currentUrl = navState.url;
};
provideMeSavedCookies = async () => {
try {
let value = await AsyncStorage.getItem('savedCookies');
if (value !== null) {
return Promise.resolve(JSON.parse(value));
}
} catch (error) {
return {}
}
};
render() {
const {cookiesString, isReady} = this.state;
if (!isReady) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<WebView
ref={this.myWebView}
source={{
uri: `${domain}`,
headers: {
Cookie: cookiesString,
},
}}
scalesPageToFit
useWebKit
onLoadEnd={this.onLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
sharedCookiesEnabled
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.WebViewStyle}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFF',
},
WebViewStyle: {
flex: 1,
resizeMode: 'cover',
},
});
Step 1:
get cookies after login and save in AsyncStorage like this
onNavigationStateChange = (navState) => {
this.currentUrl = navState.url;
};
onLoadEnd = () => {
let successUrl = `${domain}/report.php`;
if (this.currentUrl === successUrl) {
CookieManager.getAll(true).then((res) => {
AsyncStorage.setItem('savedCookies', JSON.stringify(res));
if (res.PHPSESSID) {
AsyncStorage.setItem('PHPSESSID', res.PHPSESSID.value);
}
});
}
};
Step 2:
enable sharedCookiesEnabled
props and get saved cookies in componentWillMount and make required webview header cookies formate by jsonCookiesToCookieString
function and stop render webview by isReady
props utils you get cookies
jsonCookiesToCookieString = (json) => {
let cookiesString = '';
for (let [key, value] of Object.entries(json)) {
cookiesString += `${key}=${value.value}; `;
}
return cookiesString;
};
provideMeSavedCookies = async () => {
try {
let value = await AsyncStorage.getItem('savedCookies');
if (value !== null) {
return Promise.resolve(JSON.parse(value));
}
} catch (error) {
return {}
}
};
componentWillMount() {
this.provideMeSavedCookies()
.then(async (savedCookies) => {
let cookiesString = this.jsonCookiesToCookieString(savedCookies);
const PHPSESSID = await AsyncStorage.getItem('PHPSESSID');
if (PHPSESSID) {
cookiesString += `PHPSESSID=${PHPSESSID};`;
}
this.setState({cookiesString, isReady: true});
})
.catch((e) => {
this.setState({isReady: true});
});
}
Step 3:
pass cookiesString in Webview Header and write render function like this
render() {
const {cookiesString, isReady} = this.state;
if (!isReady) {
return null;
}
return (
<SafeAreaView style={styles.container}>
<WebView
ref={this.myWebView}
source={{
uri: `${domain}`,
headers: {
Cookie: cookiesString,
},
}}
scalesPageToFit
useWebKit
onLoadEnd={this.onLoadEnd}
onNavigationStateChange={this.onNavigationStateChange}
sharedCookiesEnabled
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.WebViewStyle}
/>
</SafeAreaView>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With