2014-02-19 115 views
1

我一直在開發Android和iOS上的Web應用程序並使用Web視圖。 iPhone上的一切工作都很好,但是在Android上它並不適用於所有設備,它讓我瘋狂。在五款Android設備上效果很好,但在兩款設備上,它並沒有超出登錄頁面。但它在瀏覽器中的移動網站(而不是應用程序)上工作。Android Webview,formhash無法在某些Android設備上工作

移動應用程序無法使用的設備是HTC One(v4.3)和Acer Liquid Z3(v4.2)。另一個設備也是HTC One(v4.3),它的工作原理很難理解和解決。

應用程序打開時的第一個窗口是一個簡單的登錄窗口。在不工作的設備上,它只是重新加載頁面,用戶可以重新登錄。使用數據庫中的詳細信息檢查登錄信息。當它工作(或在瀏覽器中打開)時,它會加載到新頁面。

MainActivity.java:

public class MainActivity extends Activity { 

WebView mWebView; 
private ProgressBar loadingProgressBar; 

@SuppressLint("SetJavaScriptEnabled") 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    setContentView(R.layout.activity_main); 

    mWebView = (WebView) findViewById(R.id.webview); 

    mWebView.getSettings().setJavaScriptEnabled(true); 
    mWebView.setWebViewClient(new DivumWebViewClient()); 

    mWebView.loadUrl("http://www.xxxx.com/index.php"); 

    loadingProgressBar = (ProgressBar) findViewById(R.id.progressbar_title); 
    mWebView.setWebChromeClient(new WebChromeClient() { 
     @Override 
     public void onProgressChanged(WebView view, int newProgress) { 
      super.onProgressChanged(view, newProgress); 
      loadingProgressBar.setProgress(newProgress); 
      if (newProgress == 100) { 
       loadingProgressBar.setVisibility(View.GONE); 
      } else { 
       loadingProgressBar.setVisibility(View.VISIBLE); 
      } 
     } 
    }); 

} 

private class DivumWebViewClient extends WebViewClient { 
    @Override 
    public boolean shouldOverrideUrlLoading(WebView view, String url) { 
     view.loadUrl(url); 
     return true; 
    } 
} 
} 

的index.php

..... 
<body class="blue-bg"> 
<?php 
if (isset($_GET['error'])) { 
    echo '<p class="error">Error Logging In!</p>'; 
} 
sec_session_start(); 
if (isset($_POST['email'], $_POST['p'])) { 
    $email = $_POST['email']; 
    $password = $_POST['p']; 

    if (login($email, $password, $mysqli) == true) { 
     // Login success 
     header('Location: dashboard.php'); 
     exit; 
    } else if(login($email, $password, $mysqli) == false){ 
     $error['error'] = "<p>Enter login details:</p>\n"; 
    } 
} 
?> 
<div class="signin" style="margin-top: 0;"> 

    <div class="signin-body"> 

     <a href="index.php" title="Login" class="pull-right"> 
      <img src="../assets/images/logo.jpg" title="Login" alt="Login"> 
     </a> 
     <br><h3>Login</h3> 
     <?=$error['error']?> 
     <form action="<?=$_SERVER['PHP_SELF']?>" id="login-validatie" method="post"  name="login_form">     
      <div class="form-group"> 
      <input type="text" class="form-control" placeholder="Emailadres" name="email" id="email"> 
      </div> 

      <div class="form-group"> 
      <input type="password" class="form-control" placeholder="Wachtwoord" name="password" id="password"> 
      </div> 


      <div class="form-group clearfix"> 
      <input type="submit" onclick="formhash(this.form, this.form.password);" class="btn btn-med blue-bg pull-right" value="Inloggen"> 
      </div> 

      <hr>   
     </form> 

    </div> 

</div> 
<script src="../assets/js/scripts.js"></script>  
</body> 
</html> 

我不知道這是否是一個錯誤或東西。奇怪的是,它在大多數設備上都可以使用,但在某些設備上卻不適用它也適用於瀏覽器,這讓我覺得它與Android中的Web視圖有關。我處於死衚衕,感謝每一個幫助。謝謝!

更新 我終於找到了問題所在,它與形式散列有關。該密碼在webview中的某些Android設備上給出了不同的sha512散列,這使得無法登錄。不知道它是否是某些設備上Android Web視圖的限制,有人知道如何解決這個問題嗎?

forms.js

function formhash(form, password) { 
    // Create a new element input, this will be our hashed password field. 
    var p = document.createElement("input"); 

    // Add the new element to our form. 
    p.name = "p"; 
    p.type = "hidden"; 
    p.value = hex_sha512(password.value); 

    form.appendChild(p); 

    // Make sure the plaintext password doesn't get sent. 
    password.value = ""; 

    // Finally submit the form. 
    form.submit(); 
} 

的functions.php

function login($email, $password, $mysqli) { 
    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM x WHERE email = ? LIMIT 1")) { 
     $stmt->bind_param('s', $email); // Bind "$email" to parameter. 
     $stmt->execute(); // Execute the prepared query. 
     $stmt->store_result(); 

     // get variables from result. 
     $stmt->bind_result($user_id, $username, $db_password, $salt); 
     $stmt->fetch(); 

     // hash the password with the unique salt. 
     $password = hash('sha512', $password . $salt); 
     ?><script> var x; x = "<?php print($password); ?>"; console.log("Logging: password is " + x); </script><? 

     if ($stmt->num_rows == 1) { 
      // If the user exists we check if the account is locked 
      // from too many login attempts 

      if (checkbrute($user_id, $mysqli) == true) { 
       // Account is locked 
       // Send an email to user saying their account is locked 
       return false; 
      } else { 
       // Check if the password in the database matches 
       // the password the user submitted. 
       if ($db_password == $password) { 
        // Password is correct! 
        // Get the user-agent string of the user. 
        $user_browser = $_SERVER['HTTP_USER_AGENT']; 
        // XSS protection as we might print this value 
        $user_id = preg_replace("/[^0-9]+/", "", $user_id); 
        $_SESSION['user_id'] = $user_id; 
        // XSS protection as we might print this value 
        $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                  "", 
                  $username); 
        $_SESSION['username'] = $username; 
        $_SESSION['login_string'] = hash('sha512', 
          $password . $user_browser); 
        // Login successful. 
        return true; 
       } else { 
        // Password is not correct 
        // We record this attempt in the database 
        $now = time(); 
        $mysqli->query("INSERT INTO login_attempts(user_id, time) 
           VALUES ('$user_id', '$now')"); 
        return false; 
       } 
      } 
     } else { 
      // No user exists. 
      return false; 
     } 
    } 
} 

當在iPhone應用程序,機器人會瀏覽器,桌面瀏覽器或Android應用程式,它提供了一個sha5哈希使用:c7d9a2def4f8d0f9c4b65d7522566ed33549b266174b2b12ae7f7b047e7efed2e92d18e552d1c812f073e794d16feb8ccf9df85399c475f24571472dece2d9b2

但在某些Android設備上,當使用相同密碼出於某種奇怪的原因時,它會給出兩個哈希值之一: 98488504186f9f69041c80217c311cfb4772f46319c945d3bc30c0c2db5650e675774bc6978749770b598e70d4553ec0391e7d3ec0b56d51eef51eeadbb7e10e

a3e08c365ef82d4256d8e58fd63b53d63d50b6b3cac3cdaba395cc73289e5f955491f11f06408c2c6e6ae531d69ddb10f234ecef0cf375d9782abea27909c9ef

回答

1

我也有這個問題之前,我的WebView將無法在當前窗口中打開一個URL,很短的時間後,Android操作系統便拿起URL,並嘗試在打開它瀏覽器。我有一個非常類似的實現。

這直接從documentation是你想找什麼,因爲我相信:

Creating and setting a WebViewClient subclass. It will be called when things happen that impact the rendering of the content, eg, errors or form submissions. You can also intercept URL loading here (via shouldOverrideUrlLoading()).

shouldOverrideUrlLoading()方法告訴我想要處理通過這個網頁視圖提交的所有網址加載行動的WebView

你可以看到我在My Github Project從226行開始處理這個問題,在那裏我添加了一個擴展了WebViewClient類的額外的innerclass。

旁註

這工作在我的應用上,我支持大多數設備。但是你也可能想確保你的URL是完全合格的。我發現,當我使用任何URL沒有

的http://

在它的面前,將網頁視圖無法加載的URL甚至與其他WebViewClient。對象和shouldOverrideUrlLoading()調用。

加載失敗後,您是否嘗試過以下方法?看看它是否會刷新webview的狀態,一旦發現,請向你真正想要的URL發出新的請求。

WebView.loadUrl( 「關於:空白」)

,你試過沒有使用JavaScript的網頁視圖?

我聽說這可能是一個潛在的安全漏洞,並且它對WebView呈現網頁有不錯的影響。

祝你好運!

UPDATE

它看起來像你的問題是不是與你的WebView但你的PHP腳本是否正確?

嘗試使用這種從Java創建密碼時,或檢查,如果用戶的密碼是正確的:

String password = "123456"; 
MessageDigest md = MessageDigest.getInstance("SHA-256"); 
md.update(password.getBytes()); 
byte byteData[] = md.digest(); 

你真的只需要做到這一側或者您的應用程序或服務器腳本。我會從應用程序端選擇,因爲這樣您可以通過網絡發送散列密碼而不是純文本。

+0

謝謝,但我已經創建了一個名爲DivumWebViewClient的附加webviewclient,如代碼中所示。我也檢查了http://,那也不成問題。幾個小時後,我想我終於找到了問題。它與形式哈希和加密有關。有些Android設備會給出不同的哈希值,導致無法登錄。仍然不知道如何解決它,但找到問題有很大幫助。 :) – Leonard

+0

您可以嘗試將哈希函數更改爲兼容Java和PHP的哈希函數,以便您可以在網絡上傳遞加密密碼並在您的PHP腳本中接收它。我相信sha-256會工作,或者sha-1,但那不太安全'String password =「123456」; MessageDigest md = MessageDigest.getInstance(「SHA-256」); md.update(password.getBytes()); byte byteData [] = md.digest();' –

+0

是的我已經使用了不同的哈希函數,它現在可以在所有設備上運行。我認爲這是Android webview中的一種奇怪的錯誤。謝謝你的幫助! – Leonard

0

我已經通過使用不同的哈希函數解決了我的問題,它現在適用於所有設備。我認爲這是Android webview中的一種奇怪的錯誤。

相關問題