Login authentication in Android, Java, PHP, and MySQL
In this article, we will teach you how you can do login authentication in your android app using Java. Images will be saved via PHP.
Introduction
We will create a login form in an android application using Java. And when the form is submitted, we will send an HTTP request from android to PHP server that will check the user’s username or email and password from MySQL database and tell if the credentials are correct.
MySQL database
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` text NOT NULL,
`username` text NOT NULL,
`password` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
Users table will have a unique ID that will be used to uniquely identify the user in the whole users table. We are adding a “primary key” index to the ID field. And also an “AUTO_INCREMENT” that will automatically generate the next ID number. For example, if there are 4 users already registered and a new user tries to register, then the MySQL database will automatically assign his ID to 5.
We will also be using this unique ID to store it in shared preference in android application. Shared preference is basically a local database for an android app.
Login authentication in Android – Layout
Now come to the android part. First, we will be creating a layout for the login form. To keep the things simple, we are using username, and password in the login form:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_login"
android:padding="36dp">
<ImageView
android:id="@+id/logo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:src="@drawable/logo" />
<TextView
android:id="@+id/tv_Signin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/logo"
android:layout_marginTop="75dp"
android:layout_marginBottom="20dp"
android:text="Welcome to Chat Station"
android:textColor="#ffffff" />
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_Signin"
android:hint="Username"
android:inputType="text"
android:maxLines="1"
android:textColor="#ffffff"
android:backgroundTint="@android:color/white"
android:textColorHint="#ffffff" />
<android.support.v7.widget.AppCompatEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/username"
android:backgroundTint="@android:color/white"
android:drawablePadding="5dp"
android:hint="Password"
android:inputType="textPassword"
android:maxLines="1"
android:textColor="#ffffff"
android:textColorHint="#ffffff"
android:textCursorDrawable="@null" />
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_below="@+id/password"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:text="Login" />
</RelativeLayout>
In android, dp – Density-independent Pixels – is an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion.
- <RelativeLayout> it will have full width and height to the screen, has an image as background (as in the screenshot). Will have a padding of 36dp from all sides.
- <ImageView> to display the logo of the app or company. It has 100dp widths and 100dp height
- <TextView> to display the heading of the page.
- First <EditText> is for username. It will be below the heading. You can only write a-z and 0-9 digits, no special characters will be allowed.
- <android.support.v7.widget.AppCompatEditText> this field is for password. User cannot see the text entered in this field.
- <Button> which when clicked will submit the form and send an HTTP request to the PHP server to authenticate the user from MySQL database.
- Finally a <ProgressBar> to display a loading circle when the request is sent to the server. And will be hidden when the response is received from the server.
Send HTTP request – Volley
In your app/build.gradle, make sure to add Volley dependency:
dependencies {
....
implementation 'com.android.volley:volley:1.1.1'
}
Now in your login activity’s onCreate method paste the following code. We will explain that line-by-line:
ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setVisibility(View.GONE);
EditText username = findViewById(R.id.username);
EditText password = findViewById(R.id.password);
Button btn_login = findViewById(R.id.btn_login);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String usernameText = username.getText().toString().trim();
final String passwordText = password.getText().toString().trim();
if (!usernameText.isEmpty() && !passwordText.isEmpty()) {
progressBar.setVisibility(View.VISIBLE);
btn_login.setEnabled(false);
String url = "http://localhost/tutorials/Http.php";
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
progressBar.setVisibility(View.GONE);
btn_login.setEnabled(true);
try {
JSONObject responseJson = new JSONObject(response);
String status = responseJson.getString("status");
String message = responseJson.getString("message");
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
preference.edit().putString("userId", responseJson.getString("user_id")).apply();
startActivity(new Intent(LoginActivity.this, HomeActivity.class));
finish();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", usernameText);
params.put("password", passwordText);
params.put("login", "1");
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
// To prevent timeout error
stringRequest.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Add the request to the RequestQueue.
stringRequest.setShouldCache(false);
queue.add(stringRequest);
}
}
});
- First, we are creating an instance of ProgressBar and hiding it by default. We will only display when the request is sent.
- Then we are getting the username, and password input fields objects.
- After that, we are checking if any of the fields are empty.
- Now, we are displaying the progress bar and disabling the login button, so the user cannot click multiple times.
- Then we are sending a request using Volley. The request method should be POST.
- getParams() will have all our parameters. We are sending a username, and password along with an additional value “login” that will be used to tell the server to handle the request for login authentication.
- Response received from the server will be a JSON string, so we are converting that into JSONObject, and displaying server response message in a Toast.
- Then we are hiding the progress bar and enable the login button again. So if there is any error, then the user can click on the login button again.
- Finally, we are storing the user ID in shared preference so they can be used throughout the app. And move the user to home activity. We will be getting this user ID from PHP server-side.
Save user data – PHP, MySQL
Now come to the server-side. As you see we are sending the request to Http.php so we must have that file in our server. This file should have the following content, we will explain that line-by-line:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$conn = mysqli_connect("localhost", "root", "root", "tutorials");
if (isset($_POST["login"]))
{
$username = $_POST["username"];
$password = $_POST["password"];
$sql = "SELECT * FROM `users` WHERE `username` = '" . $username . "'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0)
{
$row = mysqli_fetch_object($result);
if (password_verify($password, $row->password))
{
echo json_encode(array(
"status" => "success",
"message" => "Successfully logged in",
"user_id" => $row->id
));
}
else
{
echo json_encode(array(
"status" => "error",
"message" => "Password does not match"
));
}
}
else
{
echo json_encode(array(
"status" => "error",
"message" => "User not found"
));
}
exit();
}
- First, we are enabling all PHP errors. So if there is any error it will be received in error response in the android app.
- Then we are connecting with the database using host: port, username, password, and database name respectively.
- After that, we are checking if the request received is for login, then get the username and password fields from a POST request.
- Now, check from the database if the provided username exists in the user’s table, if not, then send an error response and stop the script using exit() function.
- Then check the plain text password with an encrypted hashed password using password_verify. The hashed password is already been stored in the MySQL database. Learn how to save an encrypted password in the MySQL database using PHP.
- And finally, send the success response back to the android app along with user ID that will be used by the app to save in shared preference.
You can also add 2-factor authentication in it. You can also prevent the user for 30 seconds for login if the user failed to enter the correct username and password 3 times.
DIY (Do-it-yourself)
You can do the logout by removing the user ID from shared preference:
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
pref.edit().remove("userId").apply();
That’s how you can implement the login authentication functionality in your Android app. You might need this feature in your almost every upcoming android project.
You need to be a part of a contest for one of the finest blogs on the internet. I’m going to recommend this web site!