본문 바로가기
Java

[Java] Java Swing으로 회원가입 & 로그인 프로그램 만들기(1)

by teamnova 2023. 12. 8.

안녕하세요, 이번 게시글에서는 간단한 회원 가입 프로그램을 Java Swing을 이용해 만들겠습니다. 이 예제에서는 사용자로부터 이름, 아이디, 비밀번호를 입력받아 txt파일에 저장합니다. 

 

우선 시연영상입니다.

다음은 전체 코드입니다. 

import javax.swing.*; // 그래픽 사용자 인터페이스(GUI) 컴포넌트를 위한 라이브러리입니다.
import java.awt.*; // GUI 디자인과 이벤트 처리를 위한 클래스들을 포함하고 있습니다.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter; // java.io.*: 파일 입출력 기능을 위한 라이브러리입니다.
import java.io.FileWriter;
import java.io.IOException;

public class MembershipForm {
    
    public static void main(String[] args) {
        JFrame frame = new JFrame("회원 가입");
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // JFrame: 창을 나타내는 컴포넌트입니다. 제목이 "회원 가입"인 창을 생성합니다.
        // setSize(300, 200): 창의 크기를 가로 300, 세로 200으로 설정합니다.
        // setDefaultCloseOperation(...): 창의 '닫기' 버튼을 클릭하면 프로그램이 종료되도록 설정합니다.
        
        JPanel panel = new JPanel(new GridLayout(4, 2));
        // JPanel: 컴포넌트들을 담을 수 있는 컨테이너입니다.
        // new GridLayout(4, 2): 4행 2열의 그리드 레이아웃을 생성합니다.
        
        JLabel nameLabel = new JLabel("이름: ");
        JTextField nameField = new JTextField();
        // JLabel: 텍스트 라벨을 표시합니다.
        // JTextField: 사용자가 텍스트를 입력할 수 있는 필드를 생성합니다.
        
        JLabel idLabel = new JLabel("아이디: ");
        JTextField idField = new JTextField();
        
        JLabel passwordLabel = new JLabel("비밀번호: ");
        JPasswordField passwordField = new JPasswordField();
        // JPasswordField: 비밀번호를 입력 받을 때 사용되는 필드입니다. 입력 내용이 *로 가려져 보입니다.
        
        JButton registerButton = new JButton("가입하기");
        registerButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Member member = new Member(nameField.getText(), idField.getText(), new String(passwordField.getPassword()));
                saveMemberToFile(member);
                JOptionPane.showMessageDialog(frame, "가입 완료!");
            }
        });
        // JButton: 클릭 가능한 버튼을 생성합니다.
        // addActionListener(...): 버튼 클릭 시 수행할 동작을 정의합니다. 사용자가 입력한 정보를 가져와 파일에 저장하고 "가입 완료!"라는 메시지를 표시합니다.
        
        panel.add(nameLabel);
        panel.add(nameField);
        panel.add(idLabel);
        panel.add(idField);
        panel.add(passwordLabel);
        panel.add(passwordField);
        panel.add(new JLabel());
        panel.add(registerButton);
        
        frame.add(panel);
        frame.setVisible(true);
        // 마지막으로 frame.setVisible(true);를 통해 프레임(창)을 화면에 표시합니다.
    }
    
    private static void saveMemberToFile(Member member) {
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("members.txt", true))) {
            bw.write(member.toString());
            bw.newLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // BufferedWriter: 텍스트 파일에 문자를 쓰기 위한 클래스입니다.
        // FileWriter("members.txt", true): members.txt 파일에 쓰기를 위한 객체를 생성합니다. true 옵션은 파일 끝에 추가(append)하는 모드를 나타냅니다.
        // bw.write(...): 파일에 문자열을 씁니다.
        // bw.newLine(): 새 줄을 추가합니다.
    }
    
    static class Member {
        // 회원의 정보(이름, 아이디, 비밀번호)를 저장하는 클래스입니다.
        private String name;
        private String id;
        private String password;
        
        public Member(String name, String id, String password) {
            this.name = name;
            this.id = id;
            this.password = password;
        }
        
        @Override
        public String toString() {
            return "이름: " + name + ", 아이디: " + id + ", 비밀번호: " + password;
        }
    }
}

해당 프로그램의 동작 흐름은 다음과 같습니다.

1. 사용자는 프로그램을 실행하면 "회원 가입"이라는 제목의 창이 나타납니다.

2. 이름, 아이디, 비밀번호를 입력한 후 "가입하기" 버튼을 클릭합니다.

3. 클릭 이벤트가 발생하면 입력한 정보는 "Member" 객체로 만들어 집니다.

4. 이 'Member' 객체는 saveMemberToFile 함수를 통해 members.txt 파일에 저장됩니다.

5. 저장이 완료되면 "가입완료!" 라는 메시지 창이 나타납니다. 

 

주의 사항 :

(1) 실제 프로그램에서는 비밀번호를 평문으로 저장하면 안됩니다. 보안을 위해 비밀번호 암호화가 필요합니다.

(2) 또한 위의 코드에는 중복 아이디 검사나 입력 유효성 검사 등의 기능이 포함되어 있지 않습니다.

 

추가적으로 위의 코드에서 주의사항의 내용을 적용해서 기능을 추가하겠습니다.

    private static boolean isIdDuplicated(String id) {
    	// 아이디 중복 검사 메서드입니다.
        try (BufferedReader br = new BufferedReader(new FileReader("members.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                if (line.contains("아이디: " + id + ",")) {
                    return true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
    
    private static boolean isValidInput(String name, String id, String password) {
        if (name.isEmpty() || id.isEmpty() || password.isEmpty()) {
            return false;  // 필드가 비어 있는지 확인합니다.
        }
     
        if (!id.matches("[a-zA-Z][a-zA-Z0-9]*")) {
            return false;  // ID는 알파벳으로 시작하고, 알파벳 및 숫자만 포함
        }
        return true;
    }

    
    private static String hashPassword(String password) {
    	// 비밀번호 암호화하는 메서드입니다.
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(password.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

 

 

그리고 회원 가입 버튼을 눌렀을 때 호출되는 코드를 다음과 같이 수정합니다.

        registerButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String name = nameField.getText();
                String id = idField.getText();
                String password = new String(passwordField.getPassword());
                
                if (!isValidInput(name, id, password)) {
                    JOptionPane.showMessageDialog(frame, "입력이 유효하지 않습니다!");
                    return;
                }
                
                if (isIdDuplicated(id)) {
                    JOptionPane.showMessageDialog(frame, "이미 존재하는 아이디입니다!");
                    return;
                }
                
                String hashedPassword = hashPassword(password);
                Member member = new Member(name, id, hashedPassword);
                saveMemberToFile(member);
                JOptionPane.showMessageDialog(frame, "가입 완료!");
                
            }
        });

 

다음은 모든 추가사항이 적용된 시연영상입니다.