在 React Native 中从应用程序本身的 web 视图重定向到移动应用程序

Posted

技术标签:

【中文标题】在 React Native 中从应用程序本身的 web 视图重定向到移动应用程序【英文标题】:Redirection to a mobile app from the webview of the app itself in React Native 【发布时间】:2018-04-11 13:24:31 【问题描述】:

我正在构建一个需要来自外部身份验证提供程序的身份验证的 android 应用程序。所以我正在使用 react-native-oauth 包来处理这个问题。

定义的redirect_uri 是一个深层链接,理想情况下,它应该在成功验证后自行打开我的应用程序。但WebView 似乎无法处理此重定向,我收到的响应是404-page not found。

这是我编写的用于处理身份验证的服务:

    const manager = new OAuthManager('<app_name>')

    manager.addProvider(
         'provider': 
                  auth_version: '2.0', 
                  authorize_url:'<auth-url>',
                  access_token_url: '<auth-url>/token',
                  callback_url: 'http://localhost/provider',
         
    );

    manager.configure(
       provider: 
           client_id: '<id>',
           client_secret: '<secret>',
           redirect_uri: '<redirect-uri>' //DEEP LINK HERE
      
    );
   module.exports = 
      authManager: () => 
      manager.authorize('<provider>')
                        .then(resp => console.log(resp))
                        .catch(err => console.log(err));    
                    
   

我还按照how to declare the deep links for your apps 上的 Android 文档中的说明定义了我的意图过滤器。使用应用组件中的 Linking.openURL() 打开深层链接时效果很好。

非常感谢任何帮助。

【问题讨论】:

你使用的重定向 uri 是什么?另外,当您收到 404 时,网页视图中的链接是什么? @TarunLalwani 重定向 uri 是 app..com/auth 并且方案是 https 。网页视图中的链接也是一样的 请提供源代码并分配给我工作。 @Codesingh 我可以给你具体的问题 好的,我很期待 【参考方案1】:

您不能直接将 redirect_uri 设置为您的移动应用程序(因为大多数身份验证提供商不支持自定义 OAuth 方案)。

但是您可以创建一些网页来接受来自 OAuth 提供商的重定向并打开您的应用(并发送所有重定向参数,例如 token)。

例如,您创建页面https://example.com/oauth/,并将callback_url 设置为https://example.com/oauth/XXXXX_provider,因此当用户将被重定向到页面https://example.com/oauth/XXXXX_provider&amp;token=xxx 时,它将使用appName://example/oauth/google?token=xxx 打开您的应用程序

您可以使用Deeplink 处理appName://example/oauth/google?token=xxx(它会在安装到设备上时打开您的移动应用)

处理重定向的页面示例:

<html><head></head><body>
<p>Please wait while we redirect you to Your APP NAME...</p>
<p><a href="javascript:redirectToApp()">Open appname</a></p>
<script>
  var redirectToApp = function() 
    var scheme = "appnameapp";
    var openURL = "appname" + window.location.pathname + window.location.search + window.location.hash;
    var ios = /iPad|iPhone|iPod/.test(navigator.userAgent);
    var Android = /Android/.test(navigator.userAgent);
    var newLocation;
    if (iOS) 
      newLocation = scheme + ":" + openURL;
     else if (Android) 
      newLocation = "intent://" + openURL + "#Intent;scheme=" + scheme + ";package=com.appnameapp;end";
     else 
      newLocation = scheme + "://" + openURL;
    
    console.log(newLocation)
    window.location.replace(newLocation);
  
  window.onload = redirectToApp;
</script>


</body></html>

【讨论】:

我创造了这样的东西。它避免了 RN 库的所有混乱,例如 react-native-fbsdkreact-native-google-signi。这样,您可以在服务器端实现所有内容,并通过深层链接将 API 令牌传递给您的移动应用。【参考方案2】:

WebView 默认不与 Safari/Chrome 共享 cookie/会话数据。因此它不适合登录流程,因为它不使用 Chrome/Safari 中现有的登录会话。

Expo 提供了一个WebBrowser api,它将打开 Safari/Chrome 而不是 webview。请注意,它会在应用程序内打开 Safari/Chrome,而不是使用 Linking 重定向浏览器。因此,用户在浏览器中始终有一个按钮可以返回您的应用。

您可以使用WebBrowser.openAuthSessionAsync(url) 打开一个安全会话,该会话与设备中的本机浏览器共享 cookie/会话信息。

Expo 还提供了另一个名为AuthSession 的api,它简化了很多样板并提供了一个简单的api。

【讨论】:

以上是关于在 React Native 中从应用程序本身的 web 视图重定向到移动应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 React Native WebView 中从注入的 JavaScript 接收消息

在 react-native 中从 TypeScript 调用本机函数

我如何在反应原生 webview 中从网页访问当前位置

如何在 React Native 中从 ScrollView 的顶部到底部?

如何在 android 中从 react 本机应用程序播放 mov 视频?

如何在 React Native 中从屏幕上的像素获取颜色?