使用 Android 应用链接作为 OAuth2 重定向 URI

问题描述

是否可以使用以 https:// 开头的 Android 应用链接,例如:https://my-app.com/callback 在 OAuth2 流程结束时从 Android WebView 重定向回我的应用程序?我知道普通深层链接的工作原理,例如 com.my-app://my-app:// 可用于重定向回我的应用。根据我的理解,WebView 不知道如何处理此类协议,将请求传递给操作系统,如果 {{1} 中提供了足够的 IntentFilter,操作系统会将请求传递给处理此 url 的应用程序}.

这是否可以通过 AndroidManifest.xml 方案完成,否则重定向将始终被 WebView 捕获并且无法重定向回我的应用程序?

指定我想通过步骤实现的目标:

  1. https:// 中提供了一个 IntentFilter 来处理应用链接,例如:
AndroidManifest.xml
  1. <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.broWSABLE" /> <data android:scheme="http" android:host="my-app.com/callback" /> <data android:scheme="https" /> </intent-filter> 处提供了有效的 assetlinks.json(此时,https://my-app.com/.well-kNown/assetlinks.json 日志显示 JSON 验证成功,我可以从终端打开应用程序类似 IntentFilterIntent) 的命令
  2. 我的应用通过使用如下网址启动 npx uri-scheme open https://my-app.com/callback 来启动 OAuth2 流程:
CustomTabsIntent.launchUrl

完成这些步骤后,我希望我的应用程序在成功登录后打开,因为它是 url 的有效处理程序,并且不想卡在浏览器中。这是可能的,还是请求永远不会从浏览器转发到操作系统,因为浏览器是 https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=state& redirect_uri=https://my-app.com/callback& client_id=client_id 方案的有效处理程序?

如果以上是不可能的,有没有办法从 WebView 导航回应用程序,提供 https:// 或唯一的方法是使用自定义方案?

解决方法

绝对可以(并推荐)使用这样的声明式 HTTPS 方案,尽管我没有使用 WebView 这样做。

棘手的部分是,如果没有用户手势(用户点击的东西),重定向回应用程序将无法可靠地工作。用户体验和可靠性都有些棘手,您可能需要一个“插页式”互联网网页。

在移动 OAuth 中,建议使用 AppAuth Pattern,系统浏览器用于处理重定向,以便应用永远无法访问凭据。

有关更多详细信息,请参阅以下代码示例,您可以在模拟器上运行该示例。该示例链接到一些讨论优缺点的博客文章,以便您了解此类解决方案是否符合您的喜好:

,

事实证明 <data android:scheme="http" android:host="my-app.com" android:path="/callback" /> 是错误的,应该使用 android:host 代替。 path 不应包含 def load_data(path): data = pd.read_csv(path,sep=',') return data #the reason I have imported it like this is because I needed it on this form for something else. tot_data = load_data(Iris.csv) setosa = load_data(path_setosa) versicolor = load_data(path_versicolour,) virginica = load_data(path_virginica) split_data_array = [setosa,versicolor,virginica] fig,axes = plt.subplots(nrows= 2,ncols=2,sharex='col',sharey='row')#basis for subplots colors= ['blue','red','green','black'] #colors for histogram for i,ax in enumerate(axes.flat):#loop through every feature for label,color in zip(range(len(iris_names)),colors): #loop through every class _,bins,_ = ax.hist(data[label][features[i]],label=iris_names[label],color=color,stacked=True,alpha=0.5) b = np.arange(50) ax.set(xlabel='Measured [cm]',ylabel='Number of samples') #sets label name ax.label_outer() #makes the label only be on the outer part of the plots ax.legend(prop={'size': 7}) #change size of legend ax.set_title(f'Feature {i+1}: {features[i]}') #set title for each plot #ax.grid('on') #grid on or off #plt.savefig('histogram_rap.png',dpi=200) plt.show() 。我确认它在没有任何额外用户手势的情况下运行良好,就像它是一个普通的深层链接一样。浏览器实际上识别出此网址是已声明的网址,并将响应转发给应用。