Я создаю приложение Android, которое использует базу данных MySQL для хранения учетных данных пользователя, и PHP, которое запускается на сервере XAMPP на моем локальном компьютере. Я создал поток аутентификации, который использует базу данных, и приложение Android делает это через HTTP-запросы, используя PHP.
Вчера мне удалось получить рабочую аутентификацию, которая позволила мне зарегистрировать пользователя , а затем войдите, используя учетные данные этого пользователя. Сегодня я запускаю свой сервер и go для регистрации пользователя и получаю сообщение об ошибке, записанное в Android, когда вызывается функция createUser
- Unknown error occurred. Please try again!
. Я проверил журналы своего сервера, и я не обнаружил сообщений об ошибках или чего-либо, что выглядит неуместно.
Кто-нибудь знает, в чем может быть проблема? Он по-прежнему позволяет мне входить в систему, используя пользователя, которого я создал вчера, когда он работал нормально, но не разрешает дальнейшие регистрации.
регистрация. php:
<?php
require_once 'include/db_functions.php';
$db = new DB_FUNCTIONS();
$response = array("error" => FALSE);
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['password']) && isset($_POST['phone_number'])) {
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];
$phone_number = $_POST['phone_number'];
if ($db -> isExistingUser($email)) {
$response["error"] = TRUE;
$response["error_msg"] = "Email address is already registered. Please try signing in: " . $email;
echo json_encode($response);
} else {
$user = $db -> createUser($name, $email, $password, $phone_number);
if ($user) {
$response["error"] = FALSE;
$response["uid"] = $user["uid"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["phone_number"] = $user["phone_number"];
$response["user"]["created_at"] = $user["created_at"];
$response["user"]["updated_at"] = $user["updated_at"];
echo json_encode($response);
} else {
$response["error"] = TRUE;
$response["error_msg"] = "Unknown error occurred. Please try again!";
echo json_encode($response);
}
}
} else {
$response["error"] = TRUE;
$response["error_msg"] = "Some of the required parameters are missing. Please ensure all required fields are valid.";
echo json_encode($response);
}
db_functions . php:
<?php
class DB_FUNCTIONS {
private $conn;
function __construct()
{
require_once 'db_connect.php';
// Connecting to database
$db = new DB_CONNECT();
$this -> conn = $db -> connect();
}
function __destruct()
{
// TODO: Implement __destruct() method.
}
public function createUser($name, $email, $password, $phone_number) {
$uuid = uniqid('', true);
$hash = $this -> hashSSHA($password);
$encrypted_password = $hash["encrypted"];
$salt = $hash["salt"];
$sql = "INSERT INTO users(uid, name, email, password, salt, phone_number, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())";
if ($stmt = $this -> conn -> prepare($sql)) {
$stmt -> bind_param("ssssss", $uuid, $name, $email, $encrypted_password, $salt, $phone_number);
$result = $stmt -> execute();
$stmt -> close();
} else {
$error = $this -> conn -> errno . '' . $this -> conn -> error;
echo $error;
}
if ($result) {
$stmt = $this -> conn -> prepare("SELECT * FROM users WHERE email = ?");
$stmt -> bind_param("s", $email);
$stmt -> execute();
$user = $stmt -> get_result() -> fetch_assoc();
$stmt -> close();
return $user;
} else {
return false;
}
}
public function getUserByEmailAndPassword($email, $password) {
$stmt = $this -> conn -> prepare("SELECT * FROM users WHERE email = ?");
$stmt -> bind_param("s", $email);
if ($stmt -> execute()) {
$user = $stmt -> get_result() -> fetch_assoc();
$stmt -> close();
$salt = $user['salt'];
$encrypted_password = $user['password'];
$hash = $this -> checkSSHA($salt, $password);
if ($encrypted_password == $hash) {
return $user;
}
} else {
return NULL;
}
}
public function isExistingUser($email) {
$sql = "SELECT email from users WHERE email = ?";
if ($stmt = $this -> conn -> prepare($sql)) {
$stmt -> bind_param("s", $email);
$stmt -> execute();
$stmt -> store_result();
} else {
$error = $this -> conn ->errno . '' . $this -> conn -> error;
echo $error;
}
if ($stmt->num_rows > 0) {
$stmt->close();
return true;
} else {
$stmt->close();
return false;
}
}
public function hashSSHA($password) {
$salt = sha1(rand());
$salt = substr($salt, 0, 30);
$encrypted = base64_encode(sha1($password . $salt, true) . $salt);
$hash = array("salt" => $salt, "encrypted" => $encrypted);
return $hash;
}
public function checkSSHA($salt, $password) {
$hash = base64_encode(sha1($password . $salt, true) . $salt);
return $hash;
}
}
RegisterActivity. java:
package com.example.dentdevils.ui;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.example.dentdevils.MainActivity;
import com.example.dentdevils.R;
import com.example.dentdevils.helper.AppConfig;
import com.example.dentdevils.helper.AppController;
import com.example.dentdevils.helper.SQLiteHandler;
import com.example.dentdevils.helper.SessionManager;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class RegisterActivity extends AppCompatActivity {
private static final String TAG = RegisterActivity.class.getSimpleName();
private Button btnRegister;
private Button backToLogin;
private EditText inputName;
private EditText inputEmail;
private EditText inputPassword;
private EditText inputNumber;
private ProgressDialog progressDialog;
private SessionManager sessionManager;
private SQLiteHandler db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
inputName = findViewById(R.id.txtEditName);
inputEmail = findViewById(R.id.txtEditEmailAddress);
inputPassword = findViewById(R.id.txtEditPassword);
inputNumber = findViewById(R.id.txtEditPhoneNumber);
btnRegister = findViewById(R.id.btnRegister);
backToLogin = findViewById(R.id.btnBackToLogin);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
sessionManager = new SessionManager(getApplicationContext());
db = new SQLiteHandler(getApplicationContext());
if (sessionManager.isLoggedIn()) {
Intent intent = new Intent(RegisterActivity.this, HomeActivity.class);
startActivity(intent);
finish();
}
// Register Button Click Event
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = inputName.getText().toString().trim();
String email = inputEmail.getText().toString().trim();
String password = inputPassword.getText().toString().trim();
String phone_number = inputNumber.getText().toString().trim();
if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty() && !phone_number.isEmpty()) {
registerUser(name, email, password, phone_number);
} else {
Toast.makeText(getApplicationContext(), "All fields must be filled in!", Toast.LENGTH_LONG).show();
}
}
});
backToLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent backToHome = new Intent(getApplicationContext(), MainActivity.class);
startActivity(backToHome);
finish();
}
});
}
private void registerUser(final String name, final String email, final String password, final String phone_number) {
String tag_string_req = "req_register";
progressDialog.setMessage("Registering user...");
showDialog();
StringRequest stringRequest = new StringRequest(Request.Method.POST, AppConfig.URL_REGISTER, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Registration log: " + response.toString());
hideDialog();
try {
JSONObject jsonObject = new JSONObject(response);
boolean error = jsonObject.getBoolean("error");
if (!error) {
String uid = jsonObject.getString("uid");
JSONObject user = jsonObject.getJSONObject("user");
String name = user.getString("name");
String email = user.getString("email");
String phone_number = user.getString("phone_number");
String created_at = user.getString("created_at");
db.addUser(uid, name, email, phone_number, created_at);
Toast.makeText(getApplicationContext(), "User account created successfully! You may now login!", Toast.LENGTH_LONG).show();
Intent toLogin = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(toLogin);
finish();
} else {
String errorMsg = jsonObject.getString("error_msg");
Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Registration failed: " + error.getMessage());
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("name", name);
params.put("email", email);
params.put("password", password);
params.put("phone_number", phone_number);
return params;
}
};
AppController.getInstance().addToRequestQueue(stringRequest, tag_string_req);
}
private void showDialog() {
if (!progressDialog.isShowing()) {
progressDialog.show();
}
}
private void hideDialog() {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
}
mysql_error.log:
2020-07-14 13:28:28 0 [Note] InnoDB: Mutexes and rw_locks use Windows interlocked functions
2020-07-14 13:28:28 0 [Note] InnoDB: Uses event mutexes
2020-07-14 13:28:28 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2020-07-14 13:28:28 0 [Note] InnoDB: Number of pools: 1
2020-07-14 13:28:28 0 [Note] InnoDB: Using SSE2 crc32 instructions
2020-07-14 13:28:28 0 [Note] InnoDB: Initializing buffer pool, total size = 16M, instances = 1, chunk size = 16M
2020-07-14 13:28:28 0 [Note] InnoDB: Completed initialization of buffer pool
2020-07-14 13:28:28 0 [Note] InnoDB: Starting crash recovery from checkpoint LSN=628186
2020-07-14 13:28:28 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2020-07-14 13:28:28 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
2020-07-14 13:28:28 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2020-07-14 13:28:28 0 [Note] InnoDB: Setting file 'C:\xampp\xampp\mysql\data\ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2020-07-14 13:28:28 0 [Note] InnoDB: File 'C:\xampp\xampp\mysql\data\ibtmp1' size is now 12 MB.
2020-07-14 13:28:28 0 [Note] InnoDB: Waiting for purge to start
2020-07-14 13:28:28 0 [Note] InnoDB: 10.4.13 started; log sequence number 628195; transaction id 724
2020-07-14 13:28:28 0 [Note] InnoDB: Loading buffer pool(s) from C:\xampp\xampp\mysql\data\ib_buffer_pool
2020-07-14 13:28:28 0 [Note] Plugin 'FEEDBACK' is disabled.
2020-07-14 13:28:28 0 [Note] Server socket created on IP: '127.0.0.1'.
2020-07-14 13:28:28 0 [Note] InnoDB: Buffer pool(s) load completed at 200714 13:28:28
Apache error.log:
[Tue Jul 14 13:28:27.937378 2020] [core:warn] [pid 9200:tid 592] AH00098: pid file C:/xampp/xampp/apache/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
[Tue Jul 14 13:28:27.961314 2020] [mpm_winnt:notice] [pid 9200:tid 592] AH00455: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.7 configured -- resuming normal operations
[Tue Jul 14 13:28:27.961314 2020] [mpm_winnt:notice] [pid 9200:tid 592] AH00456: Apache Lounge VC15 Server built: Apr 22 2020 11:11:00
[Tue Jul 14 13:28:27.961314 2020] [core:notice] [pid 9200:tid 592] AH00094: Command line: 'c:\\xampp\\xampp\\apache\\bin\\httpd.exe -d C:/xampp/xampp/apache'
[Tue Jul 14 13:28:27.963309 2020] [mpm_winnt:notice] [pid 9200:tid 592] AH00418: Parent: Created child process 6588
[Tue Jul 14 13:28:28.387533 2020] [mpm_winnt:notice] [pid 6588:tid 740] AH00354: Child: Starting 150 worker threads.
Если что-то еще требуется, спрашивайте.