如果使用webview进行身份验证,如何使用Intent过滤器处理OAuth URL回调?

kaf*_*ein 17 authentication android callback webview oauth-2.0

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

认证

我的应用程序有一个webview作为登录屏幕,我有一个URL来加载我的webview中的身份验证表单.让我们说网址是:

https://myoauthhost.com/oauth/auth?response_type=code&client_id=XXXXXXX&redirect_uri=YYYYYYYY&scope=ZZZZZZZZZZ
Run Code Online (Sandbox Code Playgroud)

在auth活动(AuthActivity.java)中,我有以下内容:

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

在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>
Run Code Online (Sandbox Code Playgroud)

问题

在webview中使用此url(使用loadURL()方法)会重定向到另一个包含REAL OAUTH WEB FROM的 URL (应该在webview中加载).问题是此重定向会自动启动Android中的意图选择:由于URL应由Web浏览器处理,因此Android允许您选择手机上可用的Web浏览器之一来打开该URL.

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

myWebView.setWebViewClient(new WebViewClient());
Run Code Online (Sandbox Code Playgroud)

因此,使用此代码,重定向将在"webview"中处理,并显示登录屏幕.

然后我可以输入凭证(例如:通过Twitter的oauth),但是当完成身份验证时,会收到回叫,但之后应该处理应该处理回调的活动(配置为接收清单中的回调的AuthActivity).相反,我让webview显示一条消息,说明无法找到url回调(在我们的例子中:authprovider:// auth/XXX?xxx = yyy,如清单中所配置).

原因可能是以下代码:

myWebView.setWebViewClient(new WebViewClient());
Run Code Online (Sandbox Code Playgroud)

之前介绍的,告诉Android webview处理所有事情.所以现在,由于回调网址不是网址,因此无法处理它,甚至无法启动可以处理它的意图.

问题

我怎么解决这个问题 ?我应该能够让活动处理回调,但不要让webview尝试加载它.

任何帮助,将不胜感激

提前致谢

Ant*_*met 26

首先,在清单中,将这些属性设置为启动WebView的活动

android:launchMode="singleInstance" 
Run Code Online (Sandbox Code Playgroud)

并添加一个意图过滤器作为

<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>
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

这里的回调网址是
private static final String CALLBACK_URL = "oauth-testing:///";
,您正在创建动态网页视图并向用户显示.登录后,关闭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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我添加了很多代码片段,其中一些代码片段可能不相关,但我希望有一天能帮助某人.


Sha*_*med 0

好吧,首先您可能需要调用您的服务提供商提供的 URL,如果存在任何重定向,您将获得 HTTP 状态代码 3xx。接下来,如果存在任何重定向,您可以尝试调用实际的 URL。对于正常的 HTTP 响应,您将获得 HTTP 2xx 状态代码。