How to retrieve the url from a browser in react native? - react-native

I'm quite new to react native and I want to create an Instagram authentication for my app for which I need it's access token. As stated in the docs, I have to visit this link https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token and when the user has authorised and authenticated the app, I'll be redirected to this link http://your-redirect-uri#access_token=ACCESS-TOKEN from where I can grab my access token. But I'm not able to implement this as I'm unaware of the procedure on how to retrieve the token from the url in react-native once I'm redirected to this http://your-redirect-uri#access_token=ACCESS-TOKEN.
I'm using WebBrowser (Expo) to open the links in the app.
PS: I'm using CRNA cli for my react-native-app

From the example it states:
import InstagramLogin from 'react-native-instagram-login'
<View>
<TouchableOpacity onPress={()=> this.refs.instagramLogin.show()}>
<Text style={{color: 'white'}}>Login</Text>
</TouchableOpacity>
<InstagramLogin
ref='instagramLogin'
clientId='xxxxxxxxxx'
scopes={['public_content', 'follower_list']}
onLoginSuccess={(token) => this.setState({ token })}
onLoginFailure={(data) => console.log(data)}
/>
</View>
This suggests the token will be within your App state (either onLoginSuccess/Failure) is called. Access the token from there.

You can achieve Access token by using 'https://localhost' as re-direct url,
use your link in webView
eg:
<WebView
source={{
uri: "https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=https://localhost&response_type=token"
}}
onNavigationStateChange={state =>
this._onChangeNav(state)
}
/>
And add method,
_onLoadAddNewCardView(state) {
console.warn("RES=" + state.url);// Your url with ACCESS TOKEN
let responseString = state.url;
responseString = responseString.replace("https://localhost/?", "");
// Here you will get the ACCESS TOKEN
}

Related

Logout user by sending them to a Logout Webview

I'm having a difficult time trying to figure out how to log out both the user on the expo app as well as logging them out from the react-native-webview.
The user can log out of the expo app by pressing logout (which just handles the auth logic), however; the user is still logged in inside the webview (which is the shop uri).
At the moment, I came up with two possible ways: either set incognito to true on the webview, or send the user to a Screen which returns another webview to the shopify's logout uri.
// sending user to shopify logout webview
//navigator
<Stack.Navigator>
<Stack.Screen
name="AccountDetails"
component={AccountDetailsScreen}
/>
<Stack.Screen
name="ShopWebview"
component={ShopWebview}
/>
<Stack.Screen
name="LogOut"
component={LogOutWebView}
/>
</Stack.Navigator>
// from `AccountDetails` component, user presses handleLogout()
const handleLogOut = () => navigation.navigate('LogOut');
// shopify logout webview
export const LogOutWebView = () => {
return (
<WebView
source={{ uri: 'https://www.quarantotto.co.jp/account/logout' }}
/>
);
};
This seems to work w/ android, but it doesn't seem to work on iOS? I'm not quite sure why that is.
I can still set the incognito to true likeso:
// ShopWebview
<WebView
incognito
source={{ uri: 'someshop.com/' }}
/>
and this would help me not store the logged in user's session, but not quite sure if this is the proper way to handle auth.
If I can use the first method of sending the user to a webview that handles logout when a user visits it, that would be great. But not sure why it's not working from ios.
any ideas?
UPDATE: possible working solution?
Whenever the user logs out, they are sent back to a screen w/ login or register.
The issue was that whenever the user pressed login, since their session was cached, they are redirect to their account screen (which is what I don't want since if a user presses logout, I want them to be logged out and have to log back in).
what I have done is just inject some js in the LoginWebview
const handleNavigationStateChange = (newNavState) => {
if (webViewRef.current) {
webViewRef.current.injectJavaScript(scriptFetchCustomer());
}
if (newNavState.url.includes('logout')) {
setTimeout(() => {
const redirectTo = `window.location = "${someshop.com/login}"`;
webViewRef.current.injectJavaScript(redirectTo);
}, 500);
}
};
seems to work, but I don't enjoy using the settimeout. any recommendations?
second update... doesn't work on android
Android isn't working properly. I've set the source to the shopify's /account/logout uri, but inside handleNavigationStateChange the newNavState's url isn't the logout as it's set on the source.
....
Last update:
It finally works as I wanted to. I had to check for the url changes inside onNavigationStateChange of the webview. Then I could do what I wanted. I basically sent user to /account/logout, then set current logged in user state back into null which fires a redirect to login screen.
Hope it helps someone.

Accessing an intranet Sharepoint page using React Native webview

using some basic code, I am trying to access a sharepoint page:
import { WebView } from 'react-native-webview'
const ExampleScreen = ({ navigation }) => {
return (
<WebView style={{flex: 1}}
source={{uri: 'https://example.intra.net/sites/1/ProjectName/SitePages/Nameofpage.aspx'}}/>
)
}
export default ExampleScreen;
When I pull up the page on Safari, I can see it, because I'm logged in. However when I try to look at the page in the Expo Go test build, it says "401 Unauthorized". What is the process for authenticating something like this in a native app? I am a novice and I don't understand how it works.

React Native WebView - Open link in external browser only in case of user interaction

I have the following WebView component that is used multiple times for various embeds inside news articles
<WebView
useWebKit={true}
ref={(ref) => this.webview = ref}
javaScriptEnabled={true}
injectedJavaScript={"(" + injectedScript + ")()"}
onMessage={this.onMessage}
onNavigationStateChange={this.onNavigationStateChange}
{...this.props}
/>
and the following navigation state change listener, used for opening links in an external browser
onNavigationStateChange = (event) => {
this.webview.stopLoading();
Linking.openURL(event.url);
}
The problem is that the navigation change listener doesn't seem capable of differentiating between user interaction and automatic page redirects (which social media embeds will often do). How can I open the link in an external browser ONLY for user interaction?
I don't know exactly if automatic page redirects trigger click events, but they should not, so you can listen to only click events, which I suppose can only be triggered by the user.
onNavigationStateChange = (navState) =>
{
if (navState.navigationType === 'click') {
// User clicked something
}
}

Stay login in React Native WebView with expo on ios

In my react native expo app I have two screens,
One for login page where the user will put the credentials and after successful login, it will be redirected to the webview page.
Inside webpage, I’m trying to get the home page content but it's getting redirected to the index page(web login page) in ios. But in android after using domStorageEnabled={true} I’m getting home page.
How can I get the home page only using app login without login from the index page(web page login)? Please provide a solution.
Thanks in advance.
If logging in to the app is the same as logging in to the web, log in to the app and send it to the web.
const logindata = {id: id, password: password}
jsCode = `loginfunction(logindata)`; //it is web function
<WebView
source={{uri: 'https://example.com'}}
injectedJavaScript={jsCode}
style={{marginTop: 20}}
/>

instagram api login with two-factor authentication

I'm using Instagram API for authentication in my app. the API works fine but when a user is using two-factor authentication the redirect_uri doesn't work and user redirected to the Instagram main page instead of the correct URL (my app login URL). I don't know how should I handle this and couldn't find any good answer. please help me
Note: this scenario happens for the first time and when Instagram's login session is available in browser user logged in correctly.
Not sure if this is still helpful. But I implemented the following on React Native WebView component and resolved Instagram's clear misstep.
Note - A more robust solution would be for Instagram to actually solve the bug.
As props on WebView:
source={{ uri: this.state.uri }}
onNavigationStateChange={this._onNavigationStateChange}
The handling method:
_onNavigationStateChange(webViewState){
const url = webViewState.url || ''
if(url.includes('challenge')){
this.setState({challenged: true})
}
if(url === 'https://www.instagram.com/' && this.state.challenged){
this.setState({
uri: `${URI}&indifferent_query_param=${(new Date).getTime()}`
})
}
}
The handling method forces rerender of WebView and sends the user to the "authorize" page. Depending on your platform of implementation, you could apply something similar to the above.