Как передаются данные и токены между нативным приложением и React WebView
Что проверяют
Понимаете ли вы, что у нативной части и веб-кода нет общей памяти: есть только мост, по которому ходят строки, и у каждой платформы он свой. Следом почти всегда спрашивают, как передать токен так, чтобы его не утащил посторонний скрипт на странице.
Как отвечать
Начните с каналов в обе стороны:
- из веба в натив: в
react-native-webviewэтоwindow.ReactNativeWebView.postMessage(string)и пропonMessage; в чистом iOSwindow.webkit.messageHandlers.<имя>.postMessage()плюсWKScriptMessageHandler; в Android метод с аннотацией@JavascriptInterface, подключённый черезaddJavascriptInterface, или более безопасныйWebViewCompat.addWebMessageListenerсо списком разрешённых origin; - из натива в веб:
injectJavaScriptв React Native,evaluateJavaScriptв iOS,evaluateJavascriptв Android. Для данных, нужных до старта приложения, естьinjectedJavaScriptBeforeContentLoaded; - формат: мост передаёт строки, поэтому сообщения сериализуют в JSON с полями
type,idиpayload. Поidответ сопоставляется с запросом, и вызов натива в React оборачивается вPromise.
Для токена есть три рабочих варианта. Первый: натив кладёт его в cookie через CookieManager или WKHTTPCookieStore, лучше с флагом HttpOnly, тогда JS его вообще не видит. Второй: токен приходит сообщением и живёт только в памяти, не в localStorage. Третий, самый строгий: веб просит натив выполнить запрос, а токен остаётся в Keychain или Keystore. Refresh-токен в любом случае не покидает нативную часть.
Где спотыкаются
Передают токен в query-параметре URL. Он оседает в истории, логах сервера и заголовке Referer.
Не проверяют, откуда пришло сообщение. Без originWhitelist и проверки nativeEvent.url любая страница, открытая в WebView, может дёргать нативные методы.
Шлют данные до того, как React смонтировался, и сообщение теряется. Нужно рукопожатие: веб первым сообщает, что слушатель подключён, и только после этого натив отправляет токен.