User authentication is one of the most important features in modern mobile applications.
Most Android applications require:
- User Registration
- Login Authentication
- Password Security
- Database Storage
- API Communication
In this tutorial, we will build a secure Login and Registration API using:
- PHP
- MySQL
- Password Hashing
- JSON APIs
- Prepared Statements
- Android backend integration
What We Will Build
In this authentication system:
- User can register
- User can login securely
- Password hashes are stored instead of plain passwords
- Prepared statements prevent SQL Injection
- JSON responses are returned
- MySQL stores user data securely
Technologies Used
- PHP
- MySQL
- phpMyAdmin
- JSON API
- Password Hashing
- Android API Integration
Why Plain Password Storage Is Dangerous
Never store passwords directly inside databases.
Unsafe Example:
password = "123456"
If the database is compromised, all user passwords become exposed.
Modern applications should always use:
- Password hashing
- Random salt generation
- Prepared statements
Step 1 — Create Database
Open:
http://localhost/phpmyadmin/
Create a new database:
androiddeft
Step 2 — Create Member Table
Run the following SQL query:
CREATE TABLE member (
user_id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
full_name VARCHAR(50) NOT NULL,
password_hash VARCHAR(256) NOT NULL,
salt VARCHAR(256) NOT NULL,
created_date DATETIME
NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id),
UNIQUE KEY username (username)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4;
Why utf8mb4 Is Recommended?
Modern MySQL applications should use:
utf8mb4
instead of:
latin1
because it fully supports:
- Unicode
- Emoji
- International text
Project Structure
member/
│
├── db/
│ └── db_connect.php
│
├── functions.php
├── register.php
└── login.php
Step 3 — Create db_connect.php
Create:
db/db_connect.php
<?php
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_DATABASE', 'androiddeft');
define('DB_SERVER', 'localhost');
$con = mysqli_connect(
DB_SERVER,
DB_USER,
DB_PASSWORD,
DB_DATABASE
);
if (mysqli_connect_errno()) {
die(
"Database Connection Failed: "
. mysqli_connect_error()
);
}
?>
Step 4 — Create functions.php
This file handles:
- User existence check
- Salt generation
- Password hashing
<?php
$random_salt_length = 32;
function userExists($username) {
global $con;
$query =
"SELECT username
FROM member
WHERE username = ?";
if ($stmt = $con->prepare($query)) {
$stmt->bind_param(
"s",
$username
);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
$stmt->close();
return true;
}
$stmt->close();
}
return false;
}
function getSalt() {
global $random_salt_length;
return bin2hex(
random_bytes(
$random_salt_length
)
);
}
function concatPasswordWithSalt(
$password,
$salt
) {
return $password . $salt;
}
?>
Why random_bytes() Is Better?
Modern PHP applications should use:
random_bytes()
instead of older:
openssl_random_pseudo_bytes()
because it provides stronger cryptographic randomness.
Step 5 — Create register.php
This API registers new users securely.
<?php
$response = array();
include 'db/db_connect.php';
include 'functions.php';
$inputJSON =
file_get_contents('php://input');
$input =
json_decode($inputJSON, true);
if (
isset($input['username']) &&
isset($input['password']) &&
isset($input['full_name'])
) {
$username =
trim($input['username']);
$password =
trim($input['password']);
$fullName =
trim($input['full_name']);
if (!userExists($username)) {
$salt = getSalt();
$passwordHash =
password_hash(
concatPasswordWithSalt(
$password,
$salt
),
PASSWORD_DEFAULT
);
$query =
"INSERT INTO member
(username, full_name,
password_hash, salt)
VALUES (?, ?, ?, ?)";
if ($stmt = $con->prepare($query)) {
$stmt->bind_param(
"ssss",
$username,
$fullName,
$passwordHash,
$salt
);
$stmt->execute();
$response["status"] = 0;
$response["message"] =
"User Registered Successfully";
$stmt->close();
}
} else {
$response["status"] = 1;
$response["message"] =
"Username Already Exists";
}
} else {
$response["status"] = 2;
$response["message"] =
"Missing Required Parameters";
}
echo json_encode($response);
?>
Step 6 — Create login.php
This API validates login credentials securely.
<?php
$response = array();
include 'db/db_connect.php';
include 'functions.php';
$inputJSON =
file_get_contents('php://input');
$input =
json_decode($inputJSON, true);
if (
isset($input['username']) &&
isset($input['password'])
) {
$username =
trim($input['username']);
$password =
trim($input['password']);
$query =
"SELECT full_name,
password_hash,
salt
FROM member
WHERE username = ?";
if ($stmt = $con->prepare($query)) {
$stmt->bind_param(
"s",
$username
);
$stmt->execute();
$stmt->bind_result(
$fullName,
$passwordHashDB,
$salt
);
if ($stmt->fetch()) {
if (
password_verify(
concatPasswordWithSalt(
$password,
$salt
),
$passwordHashDB
)
) {
$response["status"] = 0;
$response["message"] =
"Login Successful";
$response["full_name"] =
$fullName;
} else {
$response["status"] = 1;
$response["message"] =
"Invalid Credentials";
}
} else {
$response["status"] = 1;
$response["message"] =
"Invalid Credentials";
}
$stmt->close();
}
} else {
$response["status"] = 2;
$response["message"] =
"Missing Required Parameters";
}
echo json_encode($response);
?>
How This Authentication System Works
- User registers
- Password gets salted and hashed
- Secure hash stored in MySQL
- User logs in
- Password is verified using password_verify()
- JSON response returned to Android app
Example JSON Request
Register Request
{
"username":"salil",
"password":"123456",
"full_name":"Salil Jha"
}
Success Response
{
"status":0,
"message":"Login Successful"
}
Security Improvements Over Old Tutorials
| Old Approach | Modern Secure Approach |
|---|---|
| Plain passwords | Password hashing |
| Unsafe SQL queries | Prepared statements |
| Weak salt methods | random_bytes() |
| latin1 charset | utf8mb4 charset |
Modern Backend Recommendations
Production-grade mobile applications should additionally use:
- JWT Authentication
- HTTPS
- Rate limiting
- Token refresh system
- Input validation
- Password strength rules
- Email verification
- Laravel or FastAPI backend
Common Beginner Mistakes
1. Storing Plain Passwords
Always use:
password_hash()
2. Using Raw SQL Queries
Prepared statements prevent SQL Injection attacks.
3. Ignoring HTTPS
Authentication APIs should always run on HTTPS in production.
FAQ
Can Android directly connect to MySQL?
No. Android apps should communicate through secure backend APIs.
Why use password_hash()?
It securely hashes passwords using modern algorithms.
What is the modern authentication method?
JWT Authentication with secure REST APIs is commonly used today.
Conclusion
Building secure login and registration systems is essential for modern Android applications.
Using PHP, MySQL, prepared statements, password hashing, and JSON APIs provides a solid backend authentication foundation.
Modern applications should further integrate JWT authentication, HTTPS security, token-based authorization, and scalable backend architectures for production-grade systems.
About the Author
Salil Jha is a Full Stack and Mobile Developer specializing in Android, React Native, fintech systems, scalable SaaS platforms, and developer tooling products.
CodeChain Dev — Build Modern Products. Solve Real Problems.
No comments:
Post a Comment