안드로이드 앱에서 사용자 이름과 비밀번호를 입력받아 서버에서 MySQL 데이터베이스를 통해 유효성을 검사하는 로그인 기능을 구현하는 방법을 공유합니다. 핵심은 안드로이드 클라이언트에서 서버로 데이터를 안전하게 전송하는 것입니다.
서버 측 구현 (Java Servlet)
먼저, 클라이언트로부터 요청을 받아 처리하는 간단한 서블릿을 작성합니다. 이 예제에서는 요청된 사용자 이름과 비밀번호를 콘솔에 출력하는 기능만 포함합니다. 실제 구현에서는 이 정보를 데이터베이스와 비교하여 인증을 수행합니다.
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AuthServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String userId = request.getParameter("userId");
String userPass = request.getParameter("userPass");
System.out.println("수신된 사용자 ID: " + userId);
System.out.println("수신된 비밀번호: " + userPass);
// TODO: 여기서 데이터베이스와 비교하여 인증 로직 추가
// 예: User user = userService.findByCredentials(userId, userPass);
// if (user != null) { response.setStatus(HttpServletResponse.SC_OK); } else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); }
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// POST 요청 처리는 필요에 따라 구현
}
}
위 서블릿은 클라이언트가 GET 요청으로 전달하는 `userId`와 `userPass` 파라미터를 받습니다. 데이터베이스 인증 로직은 주석으로 표시되어 있으며, 실제 프로젝트에서는 해당 부분을 채워야 합니다.
안드로이드 클라이언트 측 구현
1. MainActivity.java
로그인 화면의 UI 요소를 관리하고, 사용자가 입력한 정보를 가져와 네트워크 요청을 시작하는 액티비티입니다.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.UnsupportedEncodingException;
public class MainActivity extends Activity {
private EditText usernameInput;
private EditText passwordInput;
private Button loginButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); // 레이아웃 파일 이름 변경
usernameInput = findViewById(R.id.editTextUsername); // ID 변경
passwordInput = findViewById(R.id.editTextPassword); // ID 변경
loginButton = findViewById(R.id.buttonLogin); // ID 변경
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String enteredUsername = usernameInput.getText().toString();
String enteredPassword = passwordInput.getText().toString();
// 입력값 유효성 검사 (간단하게)
if (enteredUsername.isEmpty() || enteredPassword.isEmpty()) {
Toast.makeText(MainActivity.this, "아이디와 비밀번호를 모두 입력해주세요.", Toast.LENGTH_SHORT).show();
return;
}
// 네트워크 요청 수행 (별도의 스레드 또는 AsyncTask 사용 권장)
new Thread(new Runnable() {
@Override
public void run() {
boolean loginSuccess = false;
try {
// 서버 통신을 위한 서비스 호출
loginSuccess = AuthService.authenticateUser(enteredUsername, enteredPassword);
} catch (Exception e) {
e.printStackTrace();
// 네트워크 오류 처리
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "네트워크 오류 발생", Toast.LENGTH_SHORT).show();
}
});
}
final boolean finalLoginSuccess = loginSuccess;
runOnUiThread(new Runnable() {
@Override
public void run() {
if (finalLoginSuccess) {
Toast.makeText(MainActivity.this, "로그인 성공!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "로그인 실패. 아이디 또는 비밀번호를 확인하세요.", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
});
}
}
UI 요소의 ID를 변경했으며, 입력값 검증 로직을 추가했습니다. 또한, 네트워크 요청은 UI 스레드를 차단하지 않도록 별도의 스레드 내에서 실행되도록 수정했습니다. 성공/실패 메시지 표시는 `runOnUiThread`를 사용하여 메인 스레드에서 처리합니다.
2. activity_login.xml (레이아웃 파일)
로그인 화면의 구성을 정의하는 XML 레이아웃입니다. 입력 필드와 버튼의 ID를 위 Java 코드와 일치시킵니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="아이디" />
<EditText
android:id="@+id/editTextUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="아이디를 입력하세요"
android:inputType="text"
android:singleLine="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="비밀번호" />
<EditText
android:id="@+id/editTextPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="비밀번호를 입력하세요"
android:inputType="textPassword"
android:singleLine="true" />
<Button
android:id="@+id/buttonLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="로그인" />
</LinearLayout>
3. AuthService.java (네트워크 통신 서비스)
서버와 통신하여 로그인 인증을 처리하는 클래스입니다. GET 요청을 사용하여 파라미터를 전송합니다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
public class AuthService {
// 실제 서버 IP 주소와 포트로 변경해야 합니다.
private static final String SERVER_URL = "http://192.168.0.100:8080/YourApp/AuthServlet"; // 서버 URL 수정
/**
* 사용자 인증을 위해 서버에 요청을 보냅니다.
* @param userId 사용자 ID
* @param userPass 비밀번호
* @return 인증 성공 여부
* @throws Exception 네트워크 통신 또는 인코딩 오류
*/
public static boolean authenticateUser(String userId, String userPass) throws Exception {
// 파라미터를 URL에 안전하게 포함시키기 위해 UTF-8로 인코딩
String encodedUserId = URLEncoder.encode(userId, "UTF-8");
String encodedUserPass = URLEncoder.encode(userPass, "UTF-8");
// GET 요청 URL 생성
String requestUrl = String.format("%s?userId=%s&userPass=%s", SERVER_URL, encodedUserId, encodedUserPass);
HttpURLConnection connection = null;
try {
URL url = new URL(requestUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(15000); // 연결 타임아웃 설정
connection.setRequestMethod("GET"); // GET 메소드 사용
// 서버 응답 코드 확인
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 성공적으로 응답받은 경우 (서버에서 200 OK 반환 시)
// 실제로는 서버 응답 내용을 읽어 인증 성공 여부를 판단할 수도 있습니다.
// 여기서는 단순히 HTTP 상태 코드만으로 판단합니다.
return true;
} else {
// 오류 응답 처리
return false;
}
} finally {
if (connection != null) {
connection.disconnect(); // 연결 종료
}
}
}
// 필요하다면 POST 요청을 위한 메서드 추가
// public static boolean postRequest(...) { ... }
}
`SERVER_URL`은 실제 운영 환경에 맞게 수정해야 합니다. `HttpURLConnection`을 사용하여 GET 요청을 보내고, 서버의 HTTP 상태 코드를 확인하여 인증 성공 여부를 반환합니다. 파라미터는 `URLEncoder`를 사용하여 URL 인코딩 처리합니다.
네트워크 권한 설정
안드로이드 앱이 인터넷에 접속하려면 `AndroidManifest.xml` 파일에 인터넷 사용 권한을 추가해야 합니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
...>
<activity android:name=".MainActivity" ...>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 다른 컴포넌트들 -->
</application>
</manifest>
위 코드는 안드로이드 애플리케이션에서 서버로 로그인 정보를 전송하고 검증하는 기본적인 과정을 보여줍니다. 실제 서비스에서는 비밀번호 암호화, HTTPS 사용, 더 견고한 오류 처리 및 응답 파싱 등이 필요합니다.