Android sign-in application using web scraping with a WebView background

综合技术 2018-05-18 阅读原文

I am facing a problem when performing a login system for a web-based Android app (https connection with CA, TLS 1.0, 128bit). So, The aplication has its own login screen/activity (two EditText to username and password) and the user should be able to log into the web through that window (without showing the WebView or similar). Then the application will update its menu, Showing a number of features with a logout/exit button. Well, the problem here is that I haven't a webservice at my disposal to authenticate the user... tricks of the trade ¬ ¬.

Also, I have another problem because if the user type the wrong login although once, an evil captcha appears. We can avoid by closing and open again the browser after each attempt. Considering all possibilities, then the most 'viable' solution consist of web-scraping the Javascript code on the web, fill out the url login form fields (.do) user and password and send it. Researching and thiking the process steps, I have some doubts to implement that using Android. Ideas/advices will be appreciated. So, there we go.. my initial approach:

  1. Perform the https connection. This should validate the certificate because I can't even connect. I decided to do something like this. Download the certificates in base64 (.Cer), generate keys and using them in my application. Two questions:

    • If the web certificate expires, do you need to re-generate the keystore and add them into the app code again?.
    • Is there anyay to automate this process downloading them programmatically and validating the CA?.
  2. Create a Webview (not show) and enable the javascript. It'll serve to inject js in the web (user and pass from the EditText fields) and use the submit button on the web. Load the URL where the login form and validate it is. Question:

    b) I need to clear the webview's cache, including cookies after submitting the form in order to avoid the captcha when the user try again... in this particular case, is enough to disable the cache? (weview.clearCache (true)). I think i need to play with the onPageFinished method to control that with a firstAttemp boolean var or similar...

  3. Once you submit the form, the javascript use a label 'error', with which you could check if the login was successful. Using the Javascript Interface finding the class tag with something like:

    document.getElementsByClassName('error')[0].innerHTML

  4. If the login is correct, then save the user in the shared data file using AES encryption and BASE64 to o.

Here some code:

isSumitted = false;
    String user = editUser.getText().toString();
    String password = editPass.getText().toString();

    // Empty fields checking
    // Here we can do other checks (size, characters...)
    // maybe create a LoginFormatException...
    if (user.isEmpty() || password.isEmpty()) {
        Util.alertaAcept(getActivity(), "Error:", getResources()
                .getString(R.string.rellene_usuario_contr));
        return;
    }

    // Authenticate by using a Webview in the background
    WebView myWebView = new WebView(getActivity());
    WebSettings settings = myWebView.getSettings();
    settings.setJavaScriptEnabled(true);
    //settings.setSavePassword(false); <--- deprecated
    settings.setSaveFormData(false);
    settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
    settings.setAppCacheEnabled(false);

    // JavaScript to inject in the webview
    final StringBuilder jsCode = new StringBuilder()
    .append("javascript: {")
    .append("document.getElementById('logname')[0].value = '"+ user +"';")
    .append("document.getElementById('passtext')[0].value = '"+ password +"';");
    .append("document.getElementById('Submit').click();");

myWebView.setWebViewClient(new WebViewClient() {
    public void onPageFinished(WebView view, String url) {
       if (!isSubmitted) {
            // if first attempt
            // fill the fields and submit
            view.loadUrl(jsCode.toString());
            myWebView.loadUrl(URL_ACCESO);
            isSubmitted = true;
       }else{
            // check if the login was correct
            // by getting the response from js "document.getElementsByClassName('error')[0].innerHTML;";
            if(errorResponse.equalsIgnoreCase("")){
                 // logged OK
                 logged = true;
                  // then encrypt user & pass with AES and encode it to a String by using BASE64
                  // (plus a proper key) and save the data in the shared preference file:
             }
              else{
                  // show an AlertDialog with something like "Sorry, wrong user/password" or "Sorry, you fail this city" or whatever you want...
                  // Now, delete the browser's cache
                  //delete cached requests or cookies if it's necessary
             }
          }
      });       

Thanks! 🙂

Use web scraping tools in Android and work out with the code. Try this solution:

https://github.com/emirkin/bobik_java_sdk

The following tools and code resources can come handy to your use :

https://code.google.com/p/android-scripting/source/browse/rhino/rhino1_7R2.jar?r=835425b4ac473f2a2acfe9c4c2b92343f31b36ec

http://zscraper.wordpress.com/2012/07/03/a-comparison-shopping-android-app-without-backend/

https://gist.github.com/emirkin/3041523

Hello, buddy!

责编内容by:Hello, buddy!阅读原文】。感谢您的支持!

您可能感兴趣的

一年经验大搜车面试记录 记不太清了,一面二面合在一起写。 1.事件分发机制。 这个调试过sdk的源码, 断点调试大法好 。从activity的dispatchTouchEvent->phoneWindow->fr...
广播的最佳实践——实现强制下线功能(Android_Broadcast)... 关键词:Broadcast, 生命周期,继承 本项目基本思路: 1.先创建一个ActivityCollector类用于管理所有的活动; 2.然后创建一个BaseActivity类作为所有活动的父类: 父类功能...
Loading(二)–ThreeBodyLoadingView 这是第二个 三体动画效果图.gif 这里展示了两个不同大小的View效果,当然真正的三体几乎是没有规律的 思路 1、根据View的宽高计算三个小球的初始位置 我这里是根据宽高比重计...
浅谈JavaScript中的接口实现 一、什么是接口 接口是面向对象JavaScript程序员的工具箱中最有用的工具之一。在设计模式中提出的可重用的面向对象设计的原则之一就是“针对接口编程而不是实现编程”,即我们所说的面向接口编程,这个概念的重要性可见一斑。但问题...
在 Korok 游戏中集成广告(Android平台) 这几天我们的新游戏上线了,说实话还是挺好玩的。首发的是MAC版本,这两天发布了Android版本,Android版本的盈利方式主要考虑就是广告。此处记录一下我们在集成广告时候的一些经验。 我们的游戏引擎底层是基于 Gomobile 来...