Подтвердить что ты не робот

Как обрабатывать обратные вызовы URL-адресов OAuth с помощью фильтров Intent, если проверка подлинности выполняется с помощью webview?

Я разрабатываю приложение, использующее OAuth для аутентификации, но у меня есть небольшая проблема с обработкой обратных вызовов OAuth.

АУТЕНТИФИКАЦИЯ

Мое приложение имеет веб-просмотр в качестве экрана входа в систему, и мне предоставляется URL-адрес для загрузки формы

ПРОБЛЕМА

Этот URL-адрес при использовании в webview (с методом loadURL()) перенаправляет на другой URL-адрес, содержащий REAL OAUTH WEB FROM (который должен быть загружен в webview). Проблема в том, что это перенаправление автоматически запускает выбор намерения > на Android: поскольку URL-адрес должен обрабатываться веб-браузером, Android позволяет вам выбрать один из доступных веб-браузеров на телефон, чтобы открыть URL.

Поскольку это не то, что я хочу, я должен включить следующий код, чтобы перенаправление обрабатывалось в веб-браузере, но не запускает веб-браузер (или что-то еще):

myWebView.setWebViewClient(new WebViewClient());

поэтому с помощью этого кода перенаправление обрабатывается "в веб-просмотре", и у меня отображается экран входа.

Затем я могу ввести учетные данные (например: oauth через Twitter), но когда аутентификация завершена, возвращается обратный вызов, но затем действие, которое должно обрабатывать обратный вызов (AuthActivity, настроенный для приема обратного вызова в манифесте), является не запущен. Вместо этого у меня есть веб-представление, отображающее сообщение о том, что обратный вызов url (в нашем случае: authprovider://auth/XXX? Xxx = yyy, как указано в манифесте) не может быть найден.

Причина может заключаться в следующем:

myWebView.setWebViewClient(new WebViewClient());

представленный ранее, сообщает Android, что webview обрабатывает все. Итак, теперь, поскольку URL-адрес обратного вызова не является URL-адресом сети, он имеет проблемы с его обработкой и не может даже запустить намерение, которое может справиться с ним.

ВОПРОС

Как я могу решить эту проблему? Я должен уметь управлять обработкой обратного вызова, но не позволять веб-обозревателю загружать его.

любая помощь будет оценена

заблаговременно

4b9b3361

Ответ 1

Прежде всего в вашем манифестах, установите эти свойства в свою активность, которая запускает WebView

android:launchMode="singleInstance" 

и добавьте к нему фильтр намерений как

<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);

Здесь обратный URL-адрес private static final String CALLBACK_URL = "oauth-testing:///";
и вы создаете динамический веб-просмотр и показываете пользователю. И после входа в веб-просмотр закрывается, и код приходит в 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);
    }
}

Я знаю, что добавил много фрагментов кода, некоторые из которых могут быть неактуальными, но я надеюсь, что когда-нибудь это поможет кому-то.

Ответ 2

Ну, сначала вам может понадобиться вызывать URL-адрес, предоставленный вашим поставщиком услуг, если есть какая-либо переадресация, вы получите код статуса HTTP 3xx. Затем вы можете попытаться вызвать фактический URL-адрес, если существует какая-либо переадресация. Для нормального ответа HTTP вы получите код состояния 2x 2xx.

Ответ 3

Поскольку у вас есть объект WebView, поэтому вы можете перегрузить его, а затем обработать URL-адрес, по которому вы wana переходите к своей Деятельности, этими двумя способами.

private  class MyWebView extends WebViewClient{   
            @TargetApi(Build.VERSION_CODES.N)
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
            {
                Uri uri = request.getUrl();
                return shouldOverrideUrlLoading(uri.toString());
            }

            private boolean shouldOverrideUrlLoading(final String url)
            {
                Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
                   //your code to handle the url for navigation will go here
                try{
                      if(url.contains("yourcondition")){
                        //1st way to handle 
                        Intent intent = new Intent(Intent.ACTION_VIEW);
                        intent.setData(Uri.parse(url));
                        YourActivity.this.startActivity(intent);
                       }else{
                           //2nd way 
                        Intent intent = new Intent(YourActivity.this,NewActivity.class);
                        //you can set the data 
                        intent.setData(Uri.parse(url));
                        YourActivity.this.startActivity(intent);
                       }
                     }catch(ActivityNotFoundException e) {    
                       Log.e(LOGTAG,"Could not load url"+url);
                    }                    
               return false;
               // return true; // this True means that application wants to leave the WebView and try to go to browser and handle the url itself, otherwise return false.
             } 
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) 
    {


        try {
              if(url.contains("yourcondition")){
                //1st way to handle 
              Intent intent = new Intent(Intent.ACTION_VIEW);
              intent.setData(Uri.parse(url));
              YourActivity.this.startActivity(intent);
            }else{
           //2nd way 
            Intent intent = new Intent(YourActivity.this,NewActivity.class);
           //you can set the data 
            intent.setData(Uri.parse(url));
            YourActivity.this.startActivity(intent);
            }

        }   catch(ActivityNotFoundException e) {

            Log.e(LOGTAG,"Could not load url"+url);
        }

        return false;     
    }
}

вы можете установить mWebView.setWebViewClient(new WebViewClient()); по умолчанию, но просто добавление стандартного WebViewClient по умолчанию позволит WebView обрабатывать любые загруженные URL-адреса, т.е. в веб-браузере, а не в браузере.

но если вы перегрузитесь, пройдя выше class MyWebView, как mWebView.setWebViewClient(new MyWebView());, тогда вы можете контролировать загрузку url той же вещи, которую вы можете достичь

myWebView.setWebViewClient(new WebViewClient(){ 

                @TargetApi(Build.VERSION_CODES.N)
                @Override
                public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
                {
                    Uri uri = request.getUrl();
                    return shouldOverrideUrlLoading(uri.toString());
                }

                private boolean shouldOverrideUrlLoading(final String url)
                {
                    Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
                       //your code to handle the url for navigation will go here
                    try{
                          if(url.contains("yourcondition")){
                            //1st way to handle 
                            Intent intent = new Intent(Intent.ACTION_VIEW);
                            intent.setData(Uri.parse(url));
                            YourActivity.this.startActivity(intent);
                           }else{
                               //2nd way 
                            Intent intent = new Intent(YourActivity.this,NewActivity.class);
                            //you can set the data 
                            intent.setData(Uri.parse(url));
                            YourActivity.this.startActivity(intent);
                           }
                         }catch(ActivityNotFoundException e) {    
                           Log.e(LOGTAG,"Could not load url"+url);
                        }                    
                   return false;
                   // return true; // this True means that application wants to leave the WebView and try to go to browser and handle the url itself, otherwise return false.
                 } 

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) 
    {

        try {
             if(url.contains("yourcondition")){
             //1st way to handle
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(url));
            YourActivity.this.startActivity(intent);
            }else{
             //2nd way 
                Intent intent = new Intent(YourActivity.this,NewActivity.class);
           //you can set the data 
            intent.setData(Uri.parse(url));
            YourActivity.this.startActivity(intent);
           }    
        }   catch(ActivityNotFoundException e) {

            Log.e(LOGTAG,"Could not load url"+url);
        }

        return false;      

    }});

Если у вас нет контроля над объектом webview, это не решение, которое я обновлю после того, как я его разрешу.