android - 如果使用 webview 完成身份验证,如何使用 Intent 过滤器处理 OAuth URL 回调?

标签 android authentication webview callback oauth-2.0

我正在开发一个使用 OAuth 进行身份验证的应用,但我在处理 OAuth 回调时遇到了一点问题。

身份验证

我的应用程序有一个 webview 作为登录屏幕,并且我有一个 url 可以在我的 webview 中加载 auth 表单。假设网址是:

https://myoauthhost.com/oauth/auth?response_type=code&client_id=XXXXXXX&redirect_uri=YYYYYYYY&scope=ZZZZZZZZZZ

在身份验证 Activity (AuthActivity.java) 中,我有以下内容:

    String authURL = https://myoauthhost.com/oauth/auth?response_type=code&client_id=XXXXXXX&redirect_uri=YYYYYYYY&scope=ZZZZZZZZZZ
    myWebView.loadUrl(authURL);

在 manifest.xml 中,我有以下 oauth 回调处理:

<activity
            android:name=".AuthActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >

            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="authprovider"
                    android:scheme="auth" />
            </intent-filter>
</activity>

问题

当在 webview 中使用这个 url(使用 loadURL() 方法)时,会重定向到另一个包含 REAL OAUTH WEB FROM 的 url(应该在 webview 中加载)。问题是这个 redirection 会自动启动 Android 中的 intent selection :由于 URL 应该由 Web 浏览器处理,Android 允许您选择可用的 Web 浏览器之一手机打开网址。

由于这不是我想要的,我必须包含以下代码,以便在 webview 中处理重定向但不启动 web 浏览器(或其他):

myWebView.setWebViewClient(new WebViewClient());

因此,使用此代码,重定向是“在 web View 内”处理的,并且我显示了登录屏幕。

然后我可以输入凭据(例如:通过 Twitter 的 oauth),但是当身份验证完成后,会收到回调,但是应该处理回调的 Activity (AuthActivity 配置为在 list 中接收回调)是未启动。相反,我让 webview 显示一条消息,指出找不到 url 回调(在我们的例子中:authprovider://auth/XXX?xxx=yyy,如 list 中配置的那样)。

原因可能是以下代码:

myWebView.setWebViewClient(new WebViewClient());

前面介绍过,告诉Android webview 处理一切。所以现在,由于回调的url不是web url,所以处理起来很麻烦,甚至无法启动可以处理的intent。

问题

我该如何解决这个问题? 我应该能够让 Activity 处理回调,但不能让 webview 尝试加载它。

任何帮助将不胜感激

提前致谢

最佳答案

首先在 list 中,将这些属性设置为启动 WebView 的 Activity

android:launchMode="singleInstance" 

并为其添加一个 Intent 过滤器

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="oauth-testing" />
</intent-filter>

然后在你的代码中当用户点击登录按钮时

mReqToken = mTwitter.getOAuthRequestToken(CALLBACK_URL);
WebView webView = new WebView(this);
webView.requestFocus(View.FOCUS_DOWN);
webView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_UP:
            if (!v.hasFocus()) {
                v.requestFocus();
            }
            break;
        }
        return false;
    }
});
webView.loadUrl(mReqToken.getAuthenticationURL());
mainLayout.removeAllViews();
mainLayout.addView(webView);

这里是回调地址
private static final String CALLBACK_URL = "oauth-testing:///";
并且您正在创建一个动态 web View 并向用户显示。登录后,webview 关闭,代码进入 onNewIntent()。您需要在登录后实现您的功能。

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    dealWithTwitterResponse(intent);
}  
private void dealWithTwitterResponse(Intent intent) {
    Uri uri = intent.getData();
    System.out.println("URI=" + uri);
    if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
        String oauthVerifier = uri.getQueryParameter("oauth_verifier");
        authoriseNewUser(oauthVerifier);
    }
}

我知道我添加了很多代码 fragment ,其中一些可能不相关,但我希望有一天它会对某人有所帮助。

关于android - 如果使用 webview 完成身份验证,如何使用 Intent 过滤器处理 OAuth URL 回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12673862/

相关文章:

swift - 如何查看 2 个网页 View 何时完成加载? ( cocoa /swift )

android - 在 Android Studio 中将 Admob 横幅调整为屏幕大小

ios - Facebook 以小型模态视图登录

authentication - 当一个节点关闭时发生 Cassandra AuthenticationException

iphone - 用于身份验证的 Cocoa 设计模式

cocoa - 显示具有透明背景的 webview

java - webView.canGoBack() 始终为 false

android - WifiManager.getScanResults() 在 android 上返回空列表

带有 Intent.ACTION_EDIT 的 Android 4 startActivityForResult 始终返回结果代码 RESULT_CANCELED

android - 为什么显示隐含权限的 list 合并?