为什么当我输入正确的电子邮件时没有任何反应,但无论我输入正确或不正确的密码,程序仍然没有执行任何操作。就像程序没有检查密码一样,你能帮我吗?
这是我的login.php
<?php
if ($_SERVER['REQUEST_METHOD']=='POST') {
$email = $_POST['email'];
$password = $_POST['password'];
require_once 'connect.php';
$sql = "SELECT * FROM user WHERE email='$email' ";
$response = mysqli_query($conn, $sql);
$result = array();
$result['login'] = array();
if ( mysqli_num_rows($response) === 1 ) {
$row = mysqli_fetch_assoc($response);
if ( password_verify($password, $row['password']) ) { // I Think The Problem At This but i still don't know.
echo $password;
$index['name'] = $row['name'];
$index['email'] = $row['email'];
$index['id'] = $row['id'];
array_push($result['login'], $index);
$result['success'] = "1";
$result['message'] = "success";
echo json_encode($result);
mysqli_close($conn);
} else {
$result['success'] = "0";
$result['message'] = "error";
echo json_encode($result);
mysqli_close($conn);
}
}
}
?>
这是我的 SignInActivity.java//或者问题就在这里?
public class SignInActivity extends AppCompatActivity {
private EditText email,password;
private Button login;
private TextView link_regist;
private static String URL_LOGIN = "https://awalspace.com/app/imbalopunyajangandiganggu/login.php";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
email = findViewById(R.id.titEmail);
password = findViewById(R.id.titPassword);
login = findViewById(R.id.btnSignIn);
link_regist = findViewById(R.id.tvToSignUp);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String mEmail = email.getText().toString().trim();
String mPassword = password.getText().toString().trim();
if(!mEmail.isEmpty() || !mPassword.isEmpty())
{
login(mEmail,mPassword);
}
else{
email.setError("Silahkan Masukkan Email");
password.setError("Silahkan Masukkan Password");
}
}
});
}
private void login(final String email, final String password) {
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_LOGIN,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
JSONArray jsonArray =jsonObject.getJSONArray("login");
if (success.equals("1")){
for (int i = 0; i < jsonArray.length(); i++){
JSONObject object = jsonArray.getJSONObject(i);
String name = object.getString("name").trim();
String email = object.getString("email").trim();
Toast.makeText(SignInActivity.this, "Success Login. \n Your Name : "+name+"\nYour Email : "+email,Toast.LENGTH_SHORT).show();
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(SignInActivity.this, "Error "+e.toString(),Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(SignInActivity.this, "Error "+error.toString(),Toast.LENGTH_SHORT).show();
}
})
{
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("email",email);
params.put("password",password);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
最佳答案
部分答案:
首先
您对 SQL 注入(inject)持开放态度。您应该参数化您的查询。
Parameterized queries in PHP with MySQL connection
第二个
如果您将传递的密码存储在数据库中,您可以将密码
添加到您的查询中,这样您就不必进行第二次检查,或者您可以先对密码进行哈希处理,然后使用它在你的查询中。这可以避免获取过多的用户数据(以及相关的可能的数据泄漏),并避免需要第二种方法来找到正确的用户。
这显示在上面的链接中。
如果您在数据库中存储盐,我可以理解为什么您需要第二种方法,但是您可以通过 SQL 函数在 SQL 中对密码进行盐处理。 由于您没有包含 我会尽可能保持基本的内容。 (我的理念是让事情变得简单,直到需要复杂化为止。)password_verify
的代码,我们无法知道您实际上在做什么,因此
第三
即使您要获取该表中的所有列,也请指定所需的列名称。您最终可能会稍后向该表添加内容,这将导致该查询再次提取超出其需要的数据。
第四
由于您已经拥有电子邮件(这是查询的参数之一),因此您不需要从数据库获取它。
仅供引用,上面的链接单独添加每个参数,但是 mysqli_stmt_bind_param
可以一次性完成所有这些操作。
Object oriented style
mysqli_stmt::bind_param ( string $types , mixed &$var1 [, mixed &$... ] ) : bool
Procedural style
mysqli_stmt_bind_param ( mysqli_stmt $stmt , string $types , mixed &$var1 [, mixed &$... ] ) : bool
...
typesA string that contains one or more characters which specify the types for the corresponding bind variables:
...
https://www.php.net/manual/en/mysqli-stmt.bind-param.php
$stmt = mysqli_prepare($dbc, "SELECT name, id FROM users WHERE email= ? AND password = ?");
mysqli_stmt_bind_param($stmt, "ss", $email, $password); // or use a hash from a method instead of $password
mysqli_stmt_execute($stmt);
$row = mysqli_stmt_fetch($stmt);
这应该只提取一个用户,除非它不提取任何用户,因此您应该清楚地表明该用户是否有权访问您的网站/数据/其他内容。我建议发送一条实际的成功消息,您可以将其视为对您来说更具体的消息,而不是您现在拥有的通用消息。我知道您仍处于测试阶段,因此如果您还没有考虑的话,请稍后再考虑。
如果 $row
为 null,我还建议发送回 HTTP 401 消息。这样就可以 100% 保证您的客户端软件了解发生的情况,并且不会给出任何失败原因的具体信息。您仍然可以告诉用户一些更有意义的信息,例如“无法识别电子邮件和密码组合”。另外,不要指定电子邮件或密码是否错误,因为这可能会导致更容易的暴力破解。关于提示的想法有很多争议,所以我会让您自己进行研究并做出决定。
您的 Java 代码是否正确地将登录凭据发送到您的 PHP 服务器 IDK。我对此很生疏,所以我会让其他人插话,以及为什么我说这是一个部分答案。至少这个答案应该让你的 PHP 走上正轨。
关于java - 当我输入正确和错误的密码时什么都没有发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58665396/