I have a Single-Sign-On site opened in a webView. After the user logs in I need to take a cookie to request a token from the API and use it in the application for all the other requests.
This all works fine on the Android, but one the iOS there are no cookies when I do a request for the token.
WebView is configured to use shared cookie storage:
<WebView
source={{ uri: loginUrl }}
onMessage={handleSsoLogin}
injectedJavaScriptBeforeContentLoaded={JS_INTERFACE}
sharedCookiesEnabled={true}
/>
And if I inspect webView with devTools I can see the cookies. Also, if I visit SSO site again, I'm already logged it. So, cookies are persisted and used by webView. They are just not used by fetch and CookieManager doesn't access them:
const cookies = await CookieManager.get(url);
console.log({ cookies });
...
{"cookies": {}}
So, the question is, how can I get these cookies from the webView?
You need to use import CookieManager from "#react-native-community/cookies";
and in webview, you can do like this :
<WebView
cacheEnabled={false}
ref={ref => (this.webView = ref)}
source={{
uri: "http://yoururl.com"
}}
style={{ marginTop: 20 }}
onNavigationStateChange={this.navChange}
thirdPartyCookiesEnabled={true}
/>
{this.state.loading && (
<ActivityIndicator
color={"blue"}
style={{ flex: 20 }}
size={"large"}
/>
navChange = e => {
console.log("e", e);
this.setState({ loading: e.loading });
if (e.url == "http://yoururl.com/landing") {
CookieManager.getAll(true).then(res => {
console.log("CookieManager.getAll =>", res);
if (!!res) {
console.log({res})
CookieManager.clearAll(true).then(res => {
console.log("LoginScreen CookieManager.clearAll =>", res);
});
}
});
}
};
Related
I have a simple webview,see below;
<WebView
source={{ uri: 'https://example.com/',
headers: {
Cookie: 'cookies=dismiss; ui=darkmode',
},
}}
originWhitelist={['https://*']}
allowsFullscreenVideo={true}
pullToRefreshEnabled={true}
sharedCookiesEnabled={true}
geolocationEnabled={true}
/>
Now with inside my webview people can have profiles and links to third-party websites, how do I make those links to use an external web browser or expo web browser instead of loading them in my webview.
Using expo for the project.
if that url differs from the original domain, stops the loading, preventing page change, and opens it in the OS Navigator instead.
import * as Linking from 'expo-linking';
const webviewRef = useRef(null);
<WebView
ref={webviewRef}
source={{ uri : 'https://example.com/' }}
onNavigationStateChange={(event) => {
if (!event.url.includes("example.com")) {
webviewRef.stopLoading();
Linking.openURL(event.url);
}
}}
/>
I need to avoid sending cookies from my react native video implementation, but can't change the credentials behavior:
import Video from 'react-native-video';
...
const App = () => {
...
return (
<View>
<Video
source={{
uri: url,
type: 'm3u8',
credentials={false}
...
/>
</View>
);
}
I'm still getting the Cookie header on server...
The same website works absolute fine in android, however in iOS it seems to come up with this message:
Possible Unhandled Promise Rejection (id:11): Error: Unable to open URL about:blank
I also seem to get this when the site URI is linking to URLs from a different domain.
I have tried adding: originWhitelist={['*']}
Here is the Webview code:
<WebView
style={styles.flexContainer}
startInLoadingState
renderLoading={() =>
<View style={styles.container}>
<ActivityIndicator size="large" color="#ffffff" styles={styles.loader}/>
</View>
}
onMessage={event => {
parseWebData(event.nativeEvent.data);
}}
onShouldStartLoadWithRequest={event => {
if (!event.url.startsWith(base)) {
Linking.openURL(event.url)
return false
}
return true
}}
originWhitelist = {['*']}
source = {{ uri: base + uri }}
/>
1st try this one
<WebView
source={{ uri: base + uri }}
style={{ height: 400, width: 400 }}
useWebKit={true}
startInLoadingState={false}
javaScriptEnabled
domStorageEnabled
/>
onShouldStartLoadWithRequest={event => {
if (!event.url.startsWith(base)) {
Linking.openURL(event.url)
return false
}
return true
}}
This was the problem.
iOS treats any URL load with this, whereas Android only fires this on clicking.
See this post for the explanation of the issue:
onShouldStartLoadWithRequest automatically calling in iOS React Native on loading of any url in WebView, How to control it?
From the React Native WebView to be able to open the related platform of Deep Link Scheme.
For example:
When the website I am viewing is trying to trigger another app.
<WebView
style={styles.container}
originWhitelist={['*']}
bounces={false}
allowFileAccess={true}
domStorageEnabled={true}
javaScriptEnabled={true}
geolocationEnabled={true}
allowFileAccessFromFileURLS={true}
allowUniversalAccessFromFileURLs={true}
onNavigationStateChange={onNavigationStateChange}
source={{
uri:
'http://onelink.to/6vdhky',
}}
/>
https://github.com/react-native-community/react-native-webview/issues/750
https://github.com/react-native-webview/react-native-webview/pull/1136
image ref one
image ref two
I tried Linking.sendIntent() and Editing shouldOverrideUrlLoading() function in RNCWebViewManager.java but didn’t make it work. I finally ended up with https://github.com/lucasferreira/react-native-send-intent#readme
Here’s my code like:
onShouldStartLoadWithRequest={(request) => {
const { url } = request;
if (
url.startsWith('intent://') &&
url.includes('scheme=kbzpay') &&
Platform.OS === 'android'
) {
SendIntentAndroid.openChromeIntent(url);
return false;
}
return false;
}}
VAT/BTW number (optional)
Plus3dhedset
VAT/BTW number must be in NL123456789B12 format.
https://domains.google.com/registrar?favorites=0e70b499-a0f1-4bc6-850a-793c6f8392c7
<WebView
ref={webView => { this.refWeb = webView; }}
style={{
height:height,
justifyContent: 'center',
alignItems: 'center',
}}
scrollEnabled={true}
//Loading URL
source={
{
uri: initialUrl,
}
}
//Enable Javascript support
javaScriptEnabled={true}
domStorageEnabled={true}}
injectedJavaScript={injectScript}
automaticallyAdjustContentInsets = {true}
startInLoadingState={true}
onNavigationStateChange={this.onNavigationStateChange}/>
onNavigationStateChange = (navState) => {
console.log(navState);
if(navState.url===initialUrl){
this.setState({
canGoBack: navState.canGoBack,
canGoForward: navState.canGoForward,
changedUrl:false
})
}else{
this.setState({
canGoBack: navState.canGoBack,
canGoForward: navState.canGoForward,
changedUrl : true
})
}
}
I am using react-native-webview but onNavigationStatechange not updating navState url it remains same when i click internal links inside webview.
Also got to know some issue due to Single Page Application, Can anyone suggest the approach to handle and overcome this problem.