Alexandru Ianas Alexandru Ianas - 4 months ago 57
Android Question

Android Studio Login/Register System ideas

I want to make a diet helper app for android devices, using android studio and
I need ideas on what to use to implement the login/register system, I followed a tutorial on youtube but it was outdated and I ended up wasting my time, then I've read on google, that android studio has a library called volley that I can use with PHP and MySql to make the login system.

Do you have other ideas, or is that the best one to go with?

I'm open to suggestions so shoot!

Answer

Update:

I've created a post about how to do this using a PHP backend for your Android application. https://keithweaver.ca/posts/4/android-php-custom-login

Additionally to the link above, this is how you can setup a server. https://github.com/kweaver00/tutorials/blob/master/setup-server.md https://keithweaver.ca/posts/9/setup-ubuntu-server-quickly

Original Post:

This is one solution and isn't guaranteed to be the best.

You can really use anything to communicate with a server. Async Tasks or Retrofit are both popular.

Assuming you have set up a server with a LAMP stack. Make sure you have an SSL so you don't pass user information that isn't encrypted.

  1. Create a user table in mysql

Ex.

id int default->NULL AI primary-key
user varchar 250 default->null
pass varchar 250 default->null
signupdate date default-> null
  1. Create a log in sessions table of some sort

Ex. id int default->NULL AI primary-key user varchar 250 default->null token varchar 250 default->null addedDate date default->null

  1. Create a log in php script (I know this probably isnt the best way to right php code)

    $connection = mysqli_connect("localhost", "phpmysqluser", "password", "dbname") or die("Error 404: unable to connect");
    $username = $_POST['user'];
    $pass = $_POST['pass'];
    //add code to remove slashes and etc.
    $result = mysqli_query($connection, "SELECT * FROM userTable WHERE user='$username' AND pass='$pass'") or die("Error: this line has error");
    
    class response{
            public $loggedin =0;
            public $message = "";
    }
    
    $response = new response();
    if(mysqli_num_rows($result) == 1){
            $logInToken = generateLogInToken();
            //have a function that creates a unique token and stores it for X days or minutes
            $response->loggedin = 1;
            $response->message = $logInToken;
    }else{
            $response->message = "wrong info";
    }
    echo json_decode($response);
    

This should output a json file like this depending on your user and pass variables.

{
    "loggedin" : 1,
    "message" : "asdnlansdkansd"
}
  1. Right another script that passes in the log in token and user name to check if it's valid.

    $connection .... //same as above
    //well it really should be a include_once cause if you change credentials
    $token = $_POST['token'];
    $user = $_POST['user'];
    
    $registeredDate = "";
    $today = date('Y-m-d');
    $result = mysqli_query($connection, "SELECT * FROM tokenTable WHERE user='$user' AND token='$token'") or die("Error...");
    
    class response{
        public $status = 0;
    }
    $response = new response();
    if(mysqli_num_rows($result) == 1){
        //check token has been register today and if not sign them out
        while($row = mysqli_fetch_array($result)){
            $registeredDate = $row['addedDate'];
        }
        if($registeredDate == $today){
            //token is valid
            $response->status = 3;
        }else{
            //expired
            $response->status = 2;
        }
    }else{
        //user and token are not valid
        $response->status = 1;
    }
    echo json_decode($response);
    

Giving a json object like:

{
    "status" : 3
}    
  1. In your Android app on open, run the code to check if the account is valid if there is anything stored locally. Or just go to log in screen.

On splash screen in the onCreate (you dont need a splash screen, its actually not recommended but its the easiest way to explain the process):

if(userNameAndTokenStoredInSharedPref()){
    String token = getTokenFromSharedPref();
    String userName = getUserNameFromSharedPref();
    checkAgainstServer(token, userName);
}else{
    Intent openLogInWindow = new Intent(this, LogInActivity.class);
    startActivity(openLogInWindow);
}

still in the slash activity but out of the oncreate:

protected void checkAgainstServer(String token, String user){
    //using retrofit
    ThisAppRestClient.get().postCheckTokenAndUser(token, user, new Callback<UserStatusCallBack>() {
        @Override
        public void success(UserStatusCallBack userStatusCallback, retrofit.client.Response response) {
            if(userStatusCallback.getStatus() == 1){
               //Invalid token 
            }else if(userStatusCallback.getStatus() == 2){
               //Expired token
            }else if(userStatusCallback.getStatus() == 3){
               //Success
               Intent openMainWindow = new Intent(this, MainActivity.class);
               startActivity(openMainWindow);
            }
         }
         @Override
         public void failure(RetrofitError error) {
             //Retrofit errors like timeouts, etc.
         }
    }
}

The log in activity would be something like:

logBtn.setOnClickListener(new View.onClick...
    String userName = userNameEditText.getText().toString().toLowerCase().trim();
    String password = passwordEditText.getText().toString().trim();
    if(!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(password)){
         callServerLogInScript(userName, password);
    }
    userNameEditText.setText("");
    logBtn.setVisibility(View.GONE);
}

lower down the file:

protected void callServerLogInScript(String user, String pass){
    //using retrofit
    ThisAppRestClient.get().postCheckTokenAndUser(user, pass, new     Callback<LogInCallBack>() {
        @Override
        public void success(LogInCallBack logInCallback, retrofit.client.Response response) {
            if(logInCallback.getLoggedIn() == 1){
                //succssful
                storeUserNameInSharedPref(user);
                storeTokenInSharedPref(logInCallback.getMessage());
                Intent openMainActivity = new Intent(this, MainActivity.class);
                startActivity(openMainActivity);
            }else{
                //incorrect log in
                logBtn.setVisibility(View.VISIBLE);
            }
        }
        @Override
        public void failure(RetrofitError error) {
            //Retrofit errors like timeouts, etc.
        }
    }
}

The reason for not storing the user name and password directly is if the device is rooted they can manipulate the data locally but not on your server.