IT/Android

[Android] 회원가입, 로그인 만들기

김 정 환 2021. 1. 23. 15:30
반응형

본인은 어떤 앱을 만들게 되었습니다. 앱에 회원가입과 로그인 기능이 필요하게 되어서 인터넷을 찾아다녔고, '홍드로이드'님의 강의를 찾을 수 있었습니다. 그분의 강의가 대단히 도움이 되었습니다. 본인은 이 곳에 기본적인 과정을 소개하고 제가 겪은 문제를 해결하는 과정을 추가로 기록하겠습니다.

 

 

 

1. 안드로이드 스튜디오 프로젝트에 설정 추가하기

 

안드로이드 스튜디오에 하고 있는 프로젝트의 build.gradle(app)에 가서 depedencies에 volley library를 추가합니다. volley는 안드로이드 앱의 네트워킹을 더 쉽고, 빠르게 하는 HTTP 라이브러리입니다.

 

Manifest에 INTERNET 권한도 추가해 줍니다.

 

 

 

 

2. 로그인과 회원가입 화면 제작하기

원하는 디자인으로 만들어 주시면 됩니다. 저는 로그인 화면을 아래와 같이 만들어 봤습니다. 회원가입도 원하시는 디자인으로 만들어 주시면 됩니다.

 

 

3. APM(Apache PHP mysql) 설치와 연동하기

안드로이드와 통신할 서버, 그리고 DB를 만들어야 합니다. 강의에서는 dothome을 사용하였습니다. 그런데 본인은 AWS EC2를 이용해서 서버와 DB을 설치했고 연동했습니다. APM 설치 및 연동 방법은 여기에 있습니다.

 

 

 

4. php 파일 작성하기 

여기까지 하시면, web brower에서 web server를 통해 mysql에 접근할 수 있습니다. 그러면 안드로이드에서 web server로 php 파일을 보내서 mysql과 통신하는 것을 소개하겠습니다.

 

 

가장 먼저, Login.php와 Register.php를 생성해서 /var/www/html에 생성해 줍니다. 혹시, /var/www/html가 어딘지 모르시는 분들을 위해서 말씀드리자면, AWS linux 서버에 있는 경로입니다. 

 

 

강의에서 FileZilla를 사용했지만, 저는 그냥 만들겠습니다. FileZilla 설치와 사용법은 여기에 있습니다. 일단, html 디렉터리에 Login.php를 생성하여 아래 내용을 넣습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
    $con = mysqli_connect("localhost or 퍼블릭 DNS 주소""사용자 이름""비밀번호""DB 이름");
    mysqli_query($con'SET NAMES utf8');
 
    $userID = $_POST["userID"];
    $userPassword = $_POST["userPassword"];
    
    $statement = mysqli_prepare($con"SELECT userID, userPassword FROM USER WHERE userID = ? AND userPassword = ?");
    mysqli_stmt_bind_param($statement"ss"$userID$userPassword);
    mysqli_stmt_execute($statement);
 
    mysqli_stmt_bind_result($statement$userID$userPassword);
 
    $response = array();
    $response["success"= false;
 
    while(mysqli_stmt_fetch($statement)) {
        $response["success"= true;
        $response["userID"= $userID;
        $response["userPassword"= $userPassword;       
    }
 
    echo json_encode($response);
 
?>
cs

 

위 항목 중에 바꿔야 할 부분만 설명하겠습니다.

 

 

$con = mysqli_connect("localhost or 퍼블릭 DNS 주소", "사용자 이름", "비밀 번호", "DB 이름");

mysqli_connect 함수는 mysql과 연결하기 위한 함수입니다.

    - localhost or 퍼블릭 DNS 주소 : db가 있는 주소 (저는 aws ec2에 있어서 퍼블릭 DNS 주소를 넣었습니다.)

    - 사용자 이름 : mysql에 접속할 때 입력하는 사용자 이름

    - 비밀번호 : mysql에 접속할 때 입력하는 비밀번호

    - DB 이름 : 사용하는 DB 이름

 

 

$userID = $_POST["userID"];

$userPassword = $_POST["userPassword"];

POST 방식으로 안드로이드에서 로그인을 하기 위해 입력했던 ID와 비밀번호를 가져와서 변수에 담습니다. POST 방식 말고 GET 방식도 있습니다. 

 

 

$statement = mysqli_prepare($con, "SELECT userID, userPassword FROM USER WHERE userID = ? AND userPassword = ?");

DB에서 userID와 userPassword를 쿼리로 가져와서 prepared statement를 생성합니다.

 

 

mysqli_stmt_bind_param($statement"ss"$userID$userPassword);

로그인에서 가져온 userId, userPassword를 prepared statement에 바인딩합니다. 여기서 "s"는 string을 나타냅니다. "i"는 integer입니다. android에서 가져온 데이터의 형식과 DB에 저장되는 형식을 보고 설정합니다. 저는 userID와 userPassword를 string으로 받았습니다.

 

 

mysqli_stmt_bind_result($statement$userID$userPassword);

위에서 SELECT으로 userID와 userPassword에 해당하는 column을 가져왔습니다. 이 column들을 바인딩 합니다.

 

 

mysqli_stmt_fetch($statement)

prepared statement와 바인드된 column들과 비교하여 true/false/null을 리턴합니다.

 

 

만약 영상 강의를 보고 계시다면, 본인 것과 다르다는 것을 알 것 입니다. 본인은 몇 가지를 바꿨습니다.

"SELECT * FROM USER WHERE userID = ? AND userPassword = ?"에서

"SELECT userID, userPassword FROM USER WHERE userID = ? AND userPassword = ?"으로 바꿨습니다.

 

 

이제 Register.php를 생성하겠습니다. 아래 코드를 넣어주시면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
 
    $con = mysqli_connect("localhost or 퍼블릭 DNS 주소""사용자 이름""비밀번호""테이블 ");
    mysqli_query($con,'SET NAMES utf8');
 
    $userID = $_POST["userID"];
    $userPassword = $_POST["userPassword"];
    $userName = $_POST["userName"];
    $userBirth = $_POST["userBirth"];
 
    $statement = mysqli_prepare($con"INSERT INTO USER VALUES (?,?,?,?)");
    mysqli_stmt_bind_param($statement"ssss"$userID$userPassword$userName$userBirth);
    mysqli_stmt_execute($statement);
 
    mysqli_commit($con);
 
    $response = array();
    $response["success"= true;
 
    echo json_encode($response);
 
 
 
?>
 
cs

 

회원가입에 입력할 항목은 userID, userPassword, userName, userBirth입니다. 마찬가지로 간단하게 설명하겠습니다.

 

 

$statement = mysqli_prepare($con"INSERT INTO USER VALUES (?,?,?,?)");

USER 테이블에 4개의 항목을 넣을 prepared statement를 생성합니다.

 

 

mysqli_stmt_bind_param($statement"ssss"$userID$userPassword$userName$userBirth);

POST 방식으로 가져온 4개의 항목을 바인딩합니다. 모두 String 형식이기 때문에 "ssss"입니다.

 

 

mysqli_commit($con);

만약에 영상 또는 저의 과정을 그대로 따라오셨다면, 위 명령어는 필요없습니다. 그러나, 본인의 mysql에는 autocommit=off라고 해놓았습니다. 저를 가르쳐 주시는 PM님께서 mysql의 복구와 기타 상황을 고려해서 autocommit 기능을 꺼 놓으셨습니다. 따라서, autocommit=off이면 commit해주시길 바랍니다. 만약, autocommit=off인 상태에서 commit을 하지 않으면, php 파일로 쿼리가 DB에 전달은 될 것입니다. 그러나 입력이 안 될 수 있습니다. 그리고 select은 가능한 현상을 겪을 수 있습니다. 

 

 

 

5. DB 생성하기

위 과정에서 본인은 4개의 항목을 입력했습니다. userID, userPassword, userName, userBrith입니다. mysql에 만들어 보겠습니다. 방법은 여러가지 입니다. linux 서버에서 만들거나 DB tool를 사용하시면 됩니다. linux에서 해보겠습니다.

1
2
3
4
5
6
7
8
create database test;
 
create table user(
userID VARCHAR PRIMARY KEY,
userPassword VARCHAR NOT NULL,
userName VARCHAR NOT NULL,
userBirth VARCHAR NOT NULL
ENGINE = INNODB;
cs

 

 

 

6. Activity와 request 생성하기

이제 안드로이드 스튜디오로 이동해서 Activiry와 request을 만들겠습니다. 총 5개를 만들겠습니다. 

 

LoginActivity : 로그인 화면의 동작을 담을 activity

LoginRequest : 서버와 로그인 데이터를 통신할 request

RegisterActivity : 회원가입 화면의 동작을 담을 activity

RegisterRequest : 서버와 회원가입 데이터를 통신할 request

MainActivity : 로그인해서 넘어갈 activity

 

LoginActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public class LoginActivity extends Activity {
 
   EditText mID, mPassword;
    Button mIdSignInButton, mIdSignUpButton;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
 
        // Set up the login form.
       mID = (EditText) findViewById(R.id.iD);
        mPassword = (EditText) findViewById(R.id.password);
 
        // Button
        mIdSignInButton = (Button) findViewById(R.id.loginButton); // sign in button
        mIdSignUpButton = (Button) findViewById(R.id.signupButton); // sign up button
 
 
        // 로그인 버튼 클릭
        mIdSignInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String userID = mID.getText().toString();
                String userPassword = mPassword.getText().toString();
 
                Response.Listener<String> responseListener = new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try{
                            JSONObject jsonResponse = new JSONObject(response);
                            boolean success = jsonResponse.getBoolean("success");
                            if(success){
                                Toast.makeText(getApplicationContext(), "로그인에 성공했습니다.", Toast.LENGTH_SHORT).show();
 
                                String userID = jsonResponse.getString("userID");
                                String userPassword = jsonResponse.getString("userPassword");
                                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                                // 로그인 하면서 사용자 정보 넘기기
                                intent.putExtra("userID", userID);
                                intent.putExtra("userPassword", userPassword);
                                startActivity(intent);
 
                            } else {
                                Toast.makeText(getApplicationContext(), "로그인에 실패했습니다.", Toast.LENGTH_SHORT).show();
                                return;
                            }
                        } catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                };
 
                LoginRequest loginRequest = new LoginRequest(userID, userPassword, responseListener);
                RequestQueue queue = Volley.newRequestQueue(LoginActivity.this);
                queue.add(loginRequest);
 
            }
        });
 
        // 회원가입 버튼 클릭
        mIdSignUpButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), RegisterActivity.class);
                startActivity(intent);
            }
        });
 
    }
}
 
cs

 

 

LoginRequest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LoginRequest extends StringRequest {
 
    final static private String URL = ""// "http:// 퍼블릭 DSN 주소/Login.php";
    private Map<StringString> parameters;
 
    public LoginRequest(String userID, String userPassword, Response.Listener<String> listener) {
        super(Method.POST, URL, listener, null);
 
        parameters = new HashMap<>();
        parameters.put("userID", userID);
        parameters.put("userPassword", userPassword);
    }
 
    @Override
    protected Map<StringString> getParams() throws AuthFailureError{
        return parameters;
    }
}
 
cs

 

 

RegisterAcitivty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class RegisterActivity extends Activity {
 
    private Button mSubmitButton;
 
    private EditText mName, mID, mPassword, mBirth;
 
    private static String userName, userId, userPassword, userBirth;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_signup);
 
        // 값 가져오기
        mName = (EditText) findViewById(R.id.name);
        mID = (EditText) findViewById(R.id.ID);
        mPassword = (EditText) findViewById(R.id.password);
        mBirth = (EditText) findViewById(R.id.birth)
 
 
 
        // 회원 가입 버튼이 눌렸을때
        mSubmitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
 
                // 현재 입력된 정보를 string으로 가져오기
                userName = mName.getText().toString();
                userID = mID.getText().toString();
                userPassword = mPassword.getText().toString();
                userBirth = mBirth.getText().toString();
 
                // 회원가입 절차 시작
                Response.Listener<String> responseListener = new Response.Listener<String>(){
                    @Override
                    public void onResponse(String response) {
                        try{
                            // String으로 그냥 못 보냄으로 JSON Object 형태로 변형하여 전송
                            // 서버 통신하여 회원가입 성공 여부를 jsonResponse로 받음
                            JSONObject jsonResponse = new JSONObject(response);
                            boolean success = jsonResponse.getBoolean("success");
                            if(success){ // 회원가입이 가능한다면
                                Toast.makeText(getApplicationContext(), "회원가입이 완료되었습니다.", Toast.LENGTH_SHORT).show();
 
                                Intent intent = new Intent(RegisterActivity.this, LoginActivity.class );
                                startActivity(intent);
                                finish();//액티비티를 종료시킴(회원등록 창을 닫음)
 
                            }else{// 회원가입이 안된다면
                                Toast.makeText(getApplicationContext(), "회원가입에 실패했습니다. 다시 한 번 확인해 주세요.", Toast.LENGTH_SHORT).show();
                                return;
                            }
 
                        }
                        catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                };
 
                // Volley 라이브러리를 이용해서 실제 서버와 통신을 구현하는 부분
                RegisterRequest registerRequest = new RegisterRequest(userID, userPassword, userName, userBirth, responseListener);
                RequestQueue queue = Volley.newRequestQueue(RegisterActivity.this);
                queue.add(registerRequest);
 
            }
        });
    }
}
cs

 

 

RegisterRequest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class RegisterRequest extends StringRequest {
 
    // 서버 url 설정 (php 파일 연동)
    final static private String URL = ""// "http:// 퍼블릭 DNS 주소/Register.php"
    private Map<StringString> parameters;
 
 
    public RegisterRequest(String userID, String userPassword, String userName, String userBirth, Response.Listener<String> listener){
        super(Method.POST, URL, listener, null);
 
        parameters = new HashMap<>();
        parameters.put("userID", userID);
        parameters.put("userPassword", userPassword);
        parameters.put("userName", userName);
        parameters.put("userBirth", userBirth);
    }
 
 
    @Override
    protected Map<StringString> getParams() throws AuthFailureError{
        return parameters;
    }
 
}
 
cs

 

 

MainActivity

로그인으로 넘어갈 화면은 원하시는 디자인과 동작을 넣어 만들어 주세요.

 

 

 

 

7. 실행하기

저는 CPU가 AMD라서 안드로이드 시뮬레이터를 이용할 수 없었습니다. 핸드폰에 설치해 보았습니다.

 

회원가입하니 DB에 입력한 값이 저장되었습니다. 화면은 Heidisql에서 본 데이터 입니다.

가입한 정보를 가지고 로그인하니 성공했습니다. 

 

 

영상은 간단해 보였지만, 많은 장애물이 있었습니다. 차근차근 해결하니 만들 수 있었습니다. 혹여, 시도해보고 해결하지 못한 문제가 있으시면 도와드리겠습니다.

반응형

'IT > Android' 카테고리의 다른 글

emulator 라디오 끄기  (0) 2022.06.04
Android Studio에 OpenCV import하기  (0) 2020.05.14