In order to integrate the 3DS2 protocol of my payment provider (MangoPay), I have to give the BrowserInfo
data.
Here is an example:
{
"BrowserInfo": {
"AcceptHeader" : "application/json,text/javascript,*/*;q=0.01<",
"JavaEnabled": true,
"Language":"fr",
"ColorDepth": 32,
"ScreenHeight": 667,
"ScreenWidth": 375,
"TimeZoneOffset": "-120"
"UserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
"JavascriptEnabled": true
}
Currently, I am able to open a browser instance using
WebBrowser.openBrowserAsync
.
How can I retrieve those information using React Native + Expo?
The only doable way I found is a multiple steps process.
Create and host a public web page doing the following:
In a nutshell:
<!DOCTYPE html>
<html lang="en">
<body>
<script type="text/javascript">
const browserInfo = {
// Currently unable to fetch the default value automatically.
// @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values
acceptHeader: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
javaEnabled: window.navigator.javaEnabled(),
language: window.navigator.language,
colorDepth: window.screen.colorDepth,
screenHeight: window.screen.availHeight,
screenWidth: window.screen.availWidth,
timeZoneOffset: window.navigator.timeZoneOffset,
userAgent: window.navigator.userAgent,
javascriptEnabled: true,
}
console.log('browserInfo', browserInfo);
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('redirectUrl')) {
const redirectUrl = new URL(urlParams.get('redirectUrl'));
Object.entries(browserInfo).forEach(([key, value]) => {
redirectUrl.searchParams.append(key, value);
});
document.location = redirectUrl.toString();
}
</script>
</body>
</html>
On expo, you have two things to do:
WebBrowser
instance to the previous public pageExample:
import React, { FC, useCallback } from 'react';
import * as Linking from 'expo-linking';
import * as WebBrowser from 'expo-web-browser';
import * as queryString from 'query-string';
import {
Button,
} from '@kidways/apps-components';
import {
ButtonProps,
View,
} from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
const App: FC = () => {
const urlEventHandler = (event) => {
const parsedUrl = queryString.parseUrl(event.url);
const path = parsedUrl.url.split('/--/')[1];
if (
path === 'browser-info'
) {
// At this point, you have all the needed information.
console.log('browser-info', parsedUrl.query);
}
};
useFocusEffect(
useCallback(() => {
Linking.addEventListener('url', urlEventHandler);
return () => Linking.removeEventListener('url', urlEventHandler);
}, []),
);
const handleBrowserInfoTest: ButtonProps['onPress'] = () => {
WebBrowser.openBrowserAsync(
'https://your.domain/browser.html?redirectUrl='
+ Linking.createURL('browser-info')
);
}
return (
<View>
<Button
title="Browser Info"
onPress={handleBrowserInfoTest}
/>
</View>
);
};
With this code, you have a way to fetch the browser info just by pressing the button.
This solution is not ideal because of the user browser opening to achieve that, but I am afraid there is currently no other way.