Using SQlite to validate Logins in Android

2019-02-20 21:06发布

问题:

I'm trying to create a Log in screen for an app in Android. I have stored information about users in a 'users' table in a database. I'm trying to match the username and password entered at the log in screen with the values in the database using the cursor object but it doesnt work , causing the app to crash. Can someone please recommend or revise the approach, if possible with some code snippets. Will appreciate it big time, thanks.

Below is the code for the LoginForm class. (it uses a DBAdapter class to connect to the database)

package com.androidbook.LoginForm;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.Toast;

public class LoginForm extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final DBAdapter db = new DBAdapter(getBaseContext());
        final AutoCompleteTextView username = (AutoCompleteTextView)this.findViewById(R.id.AutoComUsernameLogin);
        final AutoCompleteTextView password = (AutoCompleteTextView)this.findViewById(R.id.AutoComPasswordLogin);

        Button Register = (Button) findViewById(R.id.ClicktoRegister);
        Register.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent myIntent = new Intent(view.getContext(), RegistrationForm.class);
                startActivityForResult(myIntent, 0);    
            }
        });
     //************************** LOG IN LOGIC******************************//   
        Button Login = (Button) findViewById(R.id.LoginButton);
        Login.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                final String Username = username.getText().toString();
                final String Password=  password.getText().toString();

                db.open();

                Cursor c = db.getAllTitles();

                   while(c.moveToNext())
                   {
                       String c1=c.getString(2);
                       String c2=c.getString(3);

                       if(c1 == Username)
                        {
                            if(c2 == Password)
                            {
                            Toast.makeText(LoginForm.this,                 
                            "You are succesfully logged in.",
                            Toast.LENGTH_LONG).show();

                                Intent myIntent = new Intent(view.getContext(), Menu.class);
                                startActivityForResult(myIntent, 0); 
                            }
                            else
                            {
                                Toast.makeText(LoginForm.this, "Incorrect password",Toast.LENGTH_LONG).show();
                            }
                            Intent myIntent = new Intent(view.getContext(), LoginForm.class);
                            startActivityForResult(myIntent, 0); 
                        }

                       else
                        Toast.makeText(LoginForm.this, "Incorrect",Toast.LENGTH_LONG).show();
                   }

                db.close();


            }
        });
    }
     }

回答1:

The answer by Chirag Raval above functions but is vulnerable to SQL injection. A malicious user could easily bypass the authentication mechanism with a basic SQLi payload (as long as there were at least a single entry in the database being checked against).

A parameterized query with bounded values is the more secure approach.

Fixing the code snippet:

public int Login(String username,String password)
{
    String[] selectionArgs = new String[]{username, password};
    try
    {
        int i = 0;
        Cursor c = null;
        c = db.rawQuery("select * from login_table where username=? and password=?", selectionArgs);
        c.moveToFirst();
        i = c.getCount(); 
        c.close(); 
        return i;
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return 0;
}

This simple improvement is more secure and easier to code.



回答2:

You can make one function in database class that will return the int number . if integer number is 1 then we can say that the user name and password is match other wise we can say login failed . There is no need to write complex code.

public int Login(String username,String password)
{
    try
    {
        int i = 0;
        Cursor c = null;
        c = db.rawQuery("select * from login_table where username =" + "\""+ username.trim() + "\""+" and password="+ "\""+ password.trim() + "\""+, null);
        c.moveToFirst();
        i = c.getCount(); 
        c.close(); 
        return i;
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return 0;
}


回答3:

When we try this code it asks to change type to boolean...

public int Login(String username,String password)
{
    try
    {
        int i = 0;
        Cursor c = null;
        c = db.rawQuery("select * from login_table where username =" + "\""+ username.trim() + "\""+" and password="+ "\""+ password.trim() + "\""+, null);
        c.moveToFirst();
        i = c.getCount(); 
        c.close(); 
        return i;
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return 0;
}