我一直在开发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
谢谢,但我已经创建了一个名为DivumWebViewClient的附加webviewclient,如代码中所示。我也检查了http://,那也不成问题。几个小时后,我想我终于找到了问题。它与形式哈希和加密有关。有些Android设备会给出不同的哈希值,导致无法登录。仍然不知道如何解决它,但找到问题有很大帮助。 :) – Leonard
您可以尝试将哈希函数更改为兼容Java和PHP的哈希函数,以便您可以在网络上传递加密密码并在您的PHP脚本中接收它。我相信sha-256会工作,或者sha-1,但那不太安全'String password =“123456”; MessageDigest md = MessageDigest.getInstance(“SHA-256”); md.update(password.getBytes()); byte byteData [] = md.digest();' –
是的我已经使用了不同的哈希函数,它现在可以在所有设备上运行。我认为这是Android webview中的一种奇怪的错误。谢谢你的帮助! – Leonard