웹사이트 검색

PHP MySQL을 사용한 Android 로그인 및 등록


Android 로그인 및 등록은 매우 일반적인 시나리오입니다. 사용자 정보를 원하는 모든 앱에서 등록 및 로그인 작업을 찾을 수 있습니다. 이 자습서에서는 로컬 웹 서버와 MySQL 데이터베이스를 설정합니다. 우리는 안드로이드 로그인 및 등록 응용 프로그램을 개발할 것입니다. PHP 스크립트를 사용하여 MySQL 데이터베이스에 연결합니다.

안드로이드 로그인 등록

첫 번째 단계는 백엔드 웹 서버를 만드는 것입니다. Mac OS X에서 작업 중이며 XAMPP를 사용하여 로컬 Apache 웹 서버와 MySQL 데이터베이스를 빠르게 설정할 수 있습니다.

XAMPP 서버 설정

<?php
echo "Hello, World";
?>

위의 코드에서:

  • ?php는 모든 PHP 스크립트에 대한 태그 열기를 시작합니다.
  • ?>는 Java에서 닫는 괄호와 같은 닫는 태그를 의미합니다.

MySQL 데이터베이스 설정

CREATE TABLE  `firstDB`.`users` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `username` VARCHAR( 20 ) NOT NULL ,
    `password` VARCHAR( 20 ) NOT NULL
)

PHP를 MySQL 데이터베이스에 연결

PHP 스크립트를 MySQL 데이터베이스에 연결하려면 세 가지 입력 값이 필요합니다. 다음은 XAMPP 서버의 입력 및 기본값입니다.

  • 호스트 이름: localhost
  • MySQL 사용자 이름: root
  • MySQL 암호: 비어 있습니다. \

test-connect.php 스크립트를 생성하고 htdocs->test-android 폴더에 추가해봅시다.

<?php
$host="localhost";
$user="root";
$password="";
$con=mysql_connect($host,$user,$password);
if($con) {
    echo '<h1>Connected to MySQL</h1>';
} else {
    echo '<h1>MySQL Server is not connected</h1>';
}
?>

mysql_connect()는 위에 나열된 매개변수를 사용하여 MySQL 데이터베이스에 연결하는 PHP의 내장 함수입니다. https://localhost/test_android/test-connect.php를 실행하고 출력을 확인하십시오. 연결되지 않은 경우 XAMPP 서버를 다시 시작하십시오.

Android 로그인 등록 앱

PHP와 MySQL의 기본 설정에 대해 논의했으므로 이제 Android 로그인 애플리케이션 부분으로 들어가 보겠습니다. 로그인/등록 애플리케이션을 개발할 예정입니다. 짧고 간단하게 유지하기 위해 등록 중에 사용자 이름과 이메일이 고유한지 확인합니다. 앱 로직으로 이동하기 전에 PHP 스크립트와 MySQL 데이터베이스에 대해 작업해 보겠습니다. 먼저 테이블 사용자를 삭제하고 위 애플리케이션의 맥락에서 새로운 사용자를 생성해 보겠습니다.

CREATE TABLE IF NOT EXISTS `firstDB`.`users` (
`id` int(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(70) NOT NULL,
`password` varchar(40) NOT NULL,
`email` varchar(50) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL

)

다음은 htdocs->test_android 폴더에 복사하여 붙여넣을 수 있는 PHP 스크립트입니다. <코드>config.php

<?php
    define("DB_HOST", "localhost");
    define("DB_USER", "root");
    define("DB_PASSWORD", "");
    define("DB_NAME", "firstDB");
    ?>

데이터베이스 연결을 위한 스크립트는 다음과 같습니다. db-connect.php

<?php
    
    include_once 'config.php';
    
    class DbConnect{
        
        private $connect;
        
        public function __construct(){
            
            $this->connect = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
            
            if (mysqli_connect_errno($this->connect)){
                echo "Unable to connect to MySQL Database: " . mysqli_connect_error();
            }
        }
        
        public function getDb(){
            return $this->connect;
        }
    }
    ?>

다음 스크립트에는 애플리케이션의 모든 핵심 기능이 포함되어 있습니다. <코드>사용자.php

<?php
    
    include_once 'db-connect.php';
    
    class User{
        
        private $db;
        
        private $db_table = "users";
        
        public function __construct(){
            $this->db = new DbConnect();
        }
        
        public function isLoginExist($username, $password){
            
            $query = "select * from ".$this->db_table." where username = '$username' AND password = '$password' Limit 1";
            
            $result = mysqli_query($this->db->getDb(), $query);
            
            if(mysqli_num_rows($result) > 0){
                
                mysqli_close($this->db->getDb());
                
                
                return true;
                
            }
            
            mysqli_close($this->db->getDb());
            
            return false;
            
        }
        
        public function isEmailUsernameExist($username, $email){
            
            $query = "select * from ".$this->db_table." where username = '$username' AND email = '$email'";
            
            $result = mysqli_query($this->db->getDb(), $query);
            
            if(mysqli_num_rows($result) > 0){
                
                mysqli_close($this->db->getDb());
                
                return true;
                
            }
               
            return false;
            
        }
        
        public function isValidEmail($email){
            return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
        }
        
        public function createNewRegisterUser($username, $password, $email){
              
            $isExisting = $this->isEmailUsernameExist($username, $email);
            
            if($isExisting){
                
                $json['success'] = 0;
                $json['message'] = "Error in registering. Probably the username/email already exists";
            }
            
            else{
                
            $isValid = $this->isValidEmail($email);
                
                if($isValid)
                {
                $query = "insert into ".$this->db_table." (username, password, email, created_at, updated_at) values ('$username', '$password', '$email', NOW(), NOW())";
                
                $inserted = mysqli_query($this->db->getDb(), $query);
                
                if($inserted == 1){
                    
                    $json['success'] = 1;
                    $json['message'] = "Successfully registered the user";
                    
                }else{
                    
                    $json['success'] = 0;
                    $json['message'] = "Error in registering. Probably the username/email already exists";
                    
                }
                
                mysqli_close($this->db->getDb());
                }
                else{
                    $json['success'] = 0;
                    $json['message'] = "Error in registering. Email Address is not valid";
                }
                
            }
            
            return $json;
            
        }
        
        public function loginUsers($username, $password){
            
            $json = array();
            
            $canUserLogin = $this->isLoginExist($username, $password);
            
            if($canUserLogin){
                
                $json['success'] = 1;
                $json['message'] = "Successfully logged in";
                
            }else{
                $json['success'] = 0;
                $json['message'] = "Incorrect details";
            }
            return $json;
        }
    }
    ?>

위의 코드에서 $json에는 반환된 JSONObject가 포함되어 있습니다. 다음 PHP 스크립트는 애플리케이션에서 처음 호출되는 스크립트입니다. <코드>index.php

<?php
    
    require_once 'user.php';
    
    $username = "";
    
    $password = "";
    
    $email = "";
    
    if(isset($_POST['username'])){
        
        $username = $_POST['username'];
        
    }
    
    if(isset($_POST['password'])){
        
        $password = $_POST['password'];
        
    }
    
    if(isset($_POST['email'])){
        
        $email = $_POST['email'];
        
    }
    
    $userObject = new User();
    
    // Registration
    
    if(!empty($username) && !empty($password) && !empty($email)){
        
        $hashed_password = md5($password);
        
        $json_registration = $userObject->createNewRegisterUser($username, $hashed_password, $email);
        
        echo json_encode($json_registration);
        
    }
    
    // Login
    
    if(!empty($username) && !empty($password) && empty($email)){
        
        $hashed_password = md5($password);
        
        $json_array = $userObject->loginUsers($username, $hashed_password);
        
        echo json_encode($json_array);
    }
    ?>

위의 코드에서 이메일 필드가 비어 있는지 여부를 확인합니다. 그렇다면 PHP 스크립트에서 로그인 기능을 호출하고 그렇지 않으면 등록 기능으로 이동합니다. JSON 응답은 성공(0 또는 1) 및 메시지라는 두 개의 매개변수를 반환합니다.

  • md5() 함수는 RSA Data Security, Inc. MD5 Message-Digest Algorithm을 사용하여 비밀번호의 해시 문자열을 생성합니다.
  • 이메일 주소가 유효한지 확인하기 위해 isValidEmail() 메소드를 구현했습니다. FILTER_VALIDATE_EMAIL은 PHP 버전 5.2.0 이상에서 작동합니다.

Android 로그인 등록 프로젝트 구조

Android 로그인 등록 코드

activity_main.xml 레이아웃은 아래에 정의되어 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:paddingLeft="24dp"
            android:paddingRight="24dp"
            android:id="@+id/linearLayout">

                <EditText android:id="@+id/editName"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Username"
                    android:textColor="#FF192133"
                    android:textColorHint="#A0192133"
                    android:fontFamily="sans-serif-light"
                    android:focusable="true"
                    android:focusableInTouchMode="true" />

                <EditText android:id="@+id/editPassword"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textPassword"
                    android:textColor="#FF192133"
                    android:textColorHint="#A0192133"
                    android:fontFamily="sans-serif-light"
                    android:hint="Password"
                    android:focusable="true"
                    android:focusableInTouchMode="true" />

                <EditText android:id="@+id/editEmail"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textEmailAddress"
                    android:textColor="#FF192133"
                    android:visibility="gone"
                    android:textColorHint="#A0192133"
                    android:fontFamily="sans-serif-light"
                    android:hint="Email"
                    android:focusable="true"
                    android:focusableInTouchMode="true" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/btnSignIn"
                android:text="SIGN IN"
                android:textStyle="bold"
                />

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/btnRegister"
                android:text="REGISTER"
                android:textStyle="bold"
                />

        </LinearLayout>

    </RelativeLayout>

</ScrollView>

MainActivity.java는 아래와 같습니다.

package com.journaldev.loginphpmysql;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
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 org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {


    EditText editEmail, editPassword, editName;
    Button btnSignIn, btnRegister;

    String URL= "https://10.0.3.2/test_android/index.php";

    JSONParser jsonParser=new JSONParser();

    int i=0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editEmail=(EditText)findViewById(R.id.editEmail);
        editName=(EditText)findViewById(R.id.editName);
        editPassword=(EditText)findViewById(R.id.editPassword);

        btnSignIn=(Button)findViewById(R.id.btnSignIn);
        btnRegister=(Button)findViewById(R.id.btnRegister);

        btnSignIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AttemptLogin attemptLogin= new AttemptLogin();
                attemptLogin.execute(editName.getText().toString(),editPassword.getText().toString(),"");
            }
        });

        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if(i==0)
                {
                    i=1;
                    editEmail.setVisibility(View.VISIBLE);
                    btnSignIn.setVisibility(View.GONE);
                    btnRegister.setText("CREATE ACCOUNT");
                }
                else{

                    btnRegister.setText("REGISTER");
                    editEmail.setVisibility(View.GONE);
                    btnSignIn.setVisibility(View.VISIBLE);
                    i=0;

                    AttemptLogin attemptLogin= new AttemptLogin();
                    attemptLogin.execute(editName.getText().toString(),editPassword.getText().toString(),editEmail.getText().toString());

                }

            }
        });


    }

    private class AttemptLogin extends AsyncTask<String, String, JSONObject> {

        @Override

        protected void onPreExecute() {

            super.onPreExecute();

        }

        @Override

        protected JSONObject doInBackground(String... args) {



            String email = args[2];
            String password = args[1];
            String name= args[0];

            ArrayList params = new ArrayList();
            params.add(new BasicNameValuePair("username", name));
            params.add(new BasicNameValuePair("password", password));
            if(email.length()>0)
            params.add(new BasicNameValuePair("email",email));

            JSONObject json = jsonParser.makeHttpRequest(URL, "POST", params);


            return json;

        }

        protected void onPostExecute(JSONObject result) {

            // dismiss the dialog once product deleted
            //Toast.makeText(getApplicationContext(),result,Toast.LENGTH_LONG).show();

            try {
                if (result != null) {
                    Toast.makeText(getApplicationContext(),result.getString("message"),Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Unable to retrieve any data from server", Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }


        }

    }
}

꽤 큰 코드입니다! 위의 코드에서 중요한 추론을 도출해 봅시다.

  1. https://192.168.0.143.
  2. 등록 버튼을 클릭하면 프로그래밍 방식으로 로그인 버튼을 숨기고 대신 이메일 주소 입력 텍스트 필드를 표시합니다.
  3. AttemptLogin 클래스는 백그라운드에서 로컬 호스트에 대한 네트워크 HTTP 요청을 실행합니다. 사용자 이름 비밀번호와 이메일 매개변수는 JSONParser 클래스의 makeHttpRequest(URL, "POST”, params); 메서드에서 전달되는 ArrayList에 추가됩니다.
  4. onPostExecute 메서드에서는 서버에서 반환된 메시지 문자열을 Toast 메시지로 표시합니다.

JSONParser.java 클래스는 아래와 같습니다.

package com.journaldev.loginphpmysql;

import android.util.Log;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

/**
 * Created by anupamchugh on 29/08/16.
 */
public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static JSONArray jArr = null;
    static String json = "";
    static String error = "";

    // constructor
    public JSONParser() {

    }

    // function get json from url
    // by making HTTP POST or GET mehtod
    public JSONObject makeHttpRequest(String url, String method,
                                      ArrayList params) {

        // Making HTTP request
        try {

            // check for request method
            if(method.equals("POST")){
                // request method is POST
                // defaultHttpClient
                HttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params));
                try {
                    Log.e("API123", " " +convertStreamToString(httpPost.getEntity().getContent()));
                    Log.e("API123",httpPost.getURI().toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                HttpResponse httpResponse = httpClient.execute(httpPost);
                Log.e("API123",""+httpResponse.getStatusLine().getStatusCode());
                error= String.valueOf(httpResponse.getStatusLine().getStatusCode());
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            }else if(method.equals("GET")){
                // request method is GET
                DefaultHttpClient httpClient = new DefaultHttpClient();
                String paramString = URLEncodedUtils.format(params, "utf-8");
                url += "?" + paramString;
                HttpGet httpGet = new HttpGet(url);

                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
            Log.d("API123",json);
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try to parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
            jObj.put("error_code",error);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }

    private String convertStreamToString(InputStream is) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        is.close();
        return sb.toString();
    }
}

위의 코드에서 makeHttpRequest 함수에 전달된 두 번째 매개 변수에 따라 각 클래스 HTTPPost 또는 HTTPGet을 호출합니다.

jObj.put("error_code",error);

위에서 MainActivity 클래스로 반환된 최종 JSONObject에 서버에서 반환된 응답 상태 코드를 추가하고 있습니다. 참고: AndroidManifest.xml 파일에 다음 권한을 추가하는 것을 잊지 마십시오.

<uses-permission android:name="android.permission.INTERNET"/>

많은 사용자가 이 튜토리얼의 하단에 \데이터를 검색할 수 없음\ 토스트를 받고 있다는 의견을 게시했습니다. Android 6.0 이상부터는 매니페스트의 애플리케이션 태그에 다음 특성을 추가해야 합니다. xml 파일: android:usesCleartextTraffic=\true\ 이유는 에뮬레이터/기기의 네트워크 보안이 http 호출을 수행할 수 있도록 하기 위함입니다. 아래 Android Q 에뮬레이터의 최신 스크린샷으로 출력을 확인하세요. . AndroidManifest.xml 파일의 변경 사항이 포함된 최신 소스 코드는 링크 및 Github Repository에 업데이트됩니다.

실행 중인 응용 프로그램의 출력은 다음과 같습니다.

Android 등록 사용자

아래 스크린샷에서 새 사용자를 등록하면 데이터베이스에 추가됩니다. 그런 다음 등록 중에 입력한 자격 증명을 사용하여 로그인합니다.

이것으로 PHP MySQL 튜토리얼을 사용한 Android 로그인이 종료됩니다. 아래 링크에서 프로젝트를 다운로드할 수 있습니다. 여기에는 PHP 파일이 들어 있는 test_android 폴더도 포함되어 있습니다. xampp->htdocs 폴더에 복사하세요! 행운을 빌어요.

Android 로그인 등록 PHP MySQL 프로젝트 다운로드

아래의 Github 리포지토리에서 전체 소스 코드에 액세스할 수도 있습니다.

Github 프로젝트 링크