Passing Login Details to React Native WebView - react-native

I'm trying to pass login details to a WebView, basically, my use case is, I have a login page built with React Native, after a successful login I wanted to redirect the user to a WebView login with the login details so the WebView doesn't render the login page in itself. So, to achieve this I attach the ref to webView like so
<WebView ref={webViewRef} ... />
With the login page built with ReactNative, the user will enter their credentials, once the login is successful I'll get the user details from the backend as a response to the LOGIN Post API Call, so I passed the response to the postMessage function
const response = await LOGIN({...credentials});
webviewRef.current.postMessage(response.data);
And to the React Web app, I used the below code to add the listener
window.addEventListener("message", (message) => {
alert(JSON.stringify(message.data));
});
But, I'm not getting the data with message.data.
Any workaround would highly be appreciated

You have to use injectJavaScript method on the webviewRef to send data from the app to the web(i.e., to react side). The post message will be used vice-versa i.e., to send data from react side to the app side. The solution below would solve your issue.
First on react side, set the custom function on the window object.
window.onUserLogin = function(userDetails) {
alert(`userDetails are ${JSON.stringify(userDetails)}`)
}
Now on the react-native side, you have the webViewRef. Using that please make the below call.
const USER_DETAILS = {
userName: "Haider"
};
webViewRef.current.injectJavaScript(`window.onUserLogin(${JSON.stringfy(USER_DETAILS)});true;`)

Related

react native supabase facebook login redirect callback site url

I am trying to login with facebook using Supabase on ios emulator. After logging in with Facebook, it redirects me back to localhost. I don't know exactly what to do on this side. Can you help me? I'm still very new.
const onHandleLogin = async () => {
const {data, error} = await supabase.auth.signInWithOAuth({
provider: 'facebook',
});
if (error) {
return;
}
if (data.url) {
const supported = await Linking.canOpenURL(data.url);
if (supported) {
await Linking.openURL(data.url);
}
}
};
After the login process, it still stays on the localhost address on the browser. My purpose is to send it to the application and get token information via the url, but I have no idea how.
I think I need to make changes here but I don't know what to write in the site url because it is a mobile application.
Thanks for your support and replies.
I tried to login with facebook using supabase, but after logging in, it keeps me in safari and gives token information on localhost. I want to direct the application after the login process and get the token information.
You will need to create a deep link for your React Native app: https://reactnative.dev/docs/linking and then set this as your redirect URL. Here a similar example with Flutter: https://supabase.com/docs/guides/getting-started/tutorials/with-flutter#setup-deep-links

Stripe Connect Account - return_url - Link back to Expo application

I'm on-boarding users onto Stripe connect. My node server generates a temporary HTTPS URL so that customers can sign on. According to their docs I need to provide a URL for when they complete the application.
https://stripe.com/docs/api/account_links/create#create_account_link
I have an Expo application. The user will open up the URL in their browser. However when they complete their application I would like them to go back to Expo App. If I try to use expo://MYAPP/ as the return_url, Stripe does not recognize the URL schema.
Does anyone have an idea how i can return the user back into my application after completing their on-boarding done via the browser?
For anyone one out there who runs into this post, this is was my solution. Your app has to link to a website. I am using Expo, but this is the React code to generate the link.
import * as WebBrowser from 'expo-web-browser';
import * as Linking from 'expo-linking';
const openPage = async () => {
try {
const result = await WebBrowser.openAuthSessionAsync(
`${url}?linkingUri=${Linking.createURL('/?')}`,
);
let redirectData;
if (result.url) {
redirectData = Linking.parse(result.url);
}
setstate({ result, redirectData });
} catch (error) {
console.log(error);
}
};
When you load the site, make sure to pass the URL that was generated from your backend
Backend code:
stripe.accountLinks
.create({
type: 'account_onboarding',
account: accountID,
refresh_url: `https://website.com/refresh`,
return_url: `https://website.com/return`,
})
When the user has the site open, have a button that redirects to the stripe URL.This is how i thought it went first
App -> Stripe connect
instead you have to approach it like this
App -> Website -> Stripe connect

How can I access login action response in webview in react native?

I want to reach the response returned after login in webview. But after a lot of research, I couldn't come to a conclusion.
Welcome screen. Here I am redirecting to the webview by clicking the button.
Login screen(Webview). I need to reach the response returned after logging in here.
How can I access requests and responses in webview? Or what is the correct way?
you can use injected script to send data to webview ,and postMessage to send data back to react native app
//This sends data from WebView to React Native
...
<script>
window.postMessage("Sending data from WebView");
</script>
...
//In order to get data the was sent from WebView use onMessage prop on <WebView>
...
<WebView
ref="webview"
injectedJavaScript={`
document.body.style.backgroundColor = '#f4f4f4';
true; `}
onMessage={this.onMessage}
/>
onMessage(data) {
//Prints out data that was passed.
console.log(data);
}

how to exit webview after submit in react native

If using webview for user login, we want to close the webview automatically after user submit their info. How to achieve that?
I have seen this being done when using Facebook sign in library, when user login with Facebook, it closes the website and calls the callback.
I am using 'react-native-inappbrowser-reborn'
you can do it use webView interact with js. firstly, when the user clicks the login button to submit their info, the html can post a message use window.postMessage("content") ., then in the react-native webview add onMessage handle.
<WebView
onMessage={this.onMessage}
...
/>
onMessage = (message) => {
// the message is you posted by window.postMessage
}
for react-native > 0.6; you should change to use window.ReactNativeWebView.postMessage.
Besides that, you can also use the injectJavaScripts. for more details about webview interact with js, you can read this artticle

React Native App Authentication with Instagram API

I've been trying to build a react native app that requires users to authenticate with their Instagram account. The Instagram API has a authorisation link and perhaps the only way to display that in an app would be through 'WebView' and so I used that.
The authentication workflow runs smoothly and then my server even gets the access token and user-id. But the problem is how to send this access token back to the app? I've used express-js for the 'redirect-uri' and so the WebView makes request to app.get() handler. In order to send response to same client on which the connection is opened, we must use res.send(). This would send the response to WebView, let's say I capture that using 'injectedJavaScript' but this javascript runs within WebView and so its unable to access react-native variables. In the event of a correct access-token, how would I ever navigate away from the WebView?
Any solutions to the above problems would be greatly appreciated. I suspect that there might even be problems with this approach(in my choice of WebView for this purpose, etc.), so a change of approach even entirely would also be of help. All I want is to authenticate the app users with Instagram and get my project going. Thanks a lot.
If you are using Expo, you can use AuthSessions to accomplish this (https://docs.expo.io/versions/latest/sdk/auth-session). The exact way to do it depends on whether you are using a managed workflow or a bare workflow, etc., but for managed workflow you can do the following:
Go to the Facebook Developer's console, go to your app, and add the Instagram Basic Display product.
Under Instagram Basic Display, under Valid OAuth Redirect URIs, use https://auth.expo.io/#your-expo-username/your-project-slug (project slug is in your app.json file)
On the same FB Developer page, add an Instagram tester profile and then follow the steps to authenticate that user.
In your project, install expo install expo-auth-session and import it into your Component
Also install expo-web-browser
Code your component like so:
import React, { useEffect } from 'react';
import { Button, Platform, Text, TouchableOpacity, View } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import { useAuthRequest, makeRedirectUri } from 'expo-auth-session';
WebBrowser.maybeCompleteAuthSession(); // <-- will close web window after authentication
const useProxy = Platform.select({ web: false, default: true });
const client_id = 9999999999999;
const redirect_uri = "https://auth.expo.io/#your-expo-username/your-project-slug";
const scope = "user_profile,user_media";
const site = "https://api.instagram.com/oauth/authorize?client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&scope=" + scope + "&response_type=code&state=1";
const discovery = { authorizationEndpoint: site }
const GetInstagram = () => {
const [request, response, promptAsync] = useAuthRequest({
redirectUri: makeRedirectUri({
useProxy,
native: redirect_uri
}),
scopes: [scope],
clientId: client_id
}, discovery);
useEffect(() => {
if (response?.type === 'success') {
const { code } = response.params; <--- the IG code will be returned here
console.log("code : ", code);
}
}, [response]);
return (
<View>
<TouchableOpacity onPress={ () => promptAsync({useProxy,windowFeatures: { width: 700, height: 600 }}) }>
<Text>Connect Your Instagram</Text>
</TouchableOpacity>
</View>
)
}
export default GetInstagram;
One way to accomplish this is via using deeplink. I don't think it's the best practice though.
The response from the WebView will be sent to the redirect URL you've previously setup after successful authentication. Please set the redirect URL to your app. For example, on iOS if you have URL Scheme as "myapp123" then, anytime you open your browser and type myapp123://.. it will open your app and your app should be able to get response sent from the instagram.