본문 바로가기
study

[C#] Log In 02

by yz 2022. 6. 21.

M01_Login_N.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// SQL Server 에 접속할 수 있는 클래스 라이브러리
using System.Data.SqlClient;

namespace MainForms
{
    /*********************************************************
     * NAME : M01_LOGIN
     * DESC : 시스템 로그인
     * ------------------------------------------------------
     * DATE        : 2022.06.20
     * AUTHOR      : 김유진
     * DESCRIPTION : 최초 프로그램 작성
     * ------------------------------------------------------*/

    // WinFormApplication 강의의 목표
    // C# .NetFrameWork 기본 도구와 프로그래밍 문법을 사용하여 개발 솔루션의 프레임을 만들어보고
    // 시스템 개발 프레임 소스의 원리를 이해 및 기능을 습득한다.

    public partial class M01_Login_N : Form
    {
        int iCount = 0;
        // SQL Server 커넥터 객체 생성
        private SqlConnection Connect;
        public M01_Login_N()
        {
            InitializeComponent();
            Commons.sConnectInfo = "Server = localhost; Uid = sa; Pwd = 1234; database = AppDev";
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            // 로그인 버튼 클릭
            DoLogin();

            if (iCount == 3)
            {
                MessageBox.Show("해킹이 감지되었습니다");
                this.Close();
            }
        }
        private void DoLogin()
        {
            try
            {
                // 데이터베이스 접속 경로 설정
                string strConn = Commons.sConnectInfo;

                // 접속 경로 커넥터 객체에 전달
                Connect = new SqlConnection(strConn);

                // 데이터베이스 접속 여부 확인
                Connect.Open();
                if (Connect.State != System.Data.ConnectionState.Open)
                {
                    MessageBox.Show("데이터박스 연결에 실패하였습니다.");
                    return;
                }

                string sLogInID = txtID.Text; // 사용자 ID
                string sPassWord = txtPW.Text; // 사용자 비밀번호

                // ID / PW 찾는 sql 구문
                string sFindUserSQL = " SELECT USERNAME,PW,ISNULL(PW_F_CNT,0) AS PW_F_CNT";
                sFindUserSQL       += "   FROM TB_USER";
                sFindUserSQL       += $" WHERE USERID = '{sLogInID}'";
                //sFindUserSQL       += $"   AND PW = '{sPassWord}'"; 

                // SqlDataAdapter : 데이터베이스에 연결 후 SELECT SQL 구문 전달. 결과값 리턴받는 클래스
                SqlDataAdapter Adapter = new SqlDataAdapter(sFindUserSQL, Connect);
                // DataTable : 프로그래밍 언어에서 데이터를 DB 의 테이블 형태로 관리하는 데이터 자료 구조 클래스
                // DQL 서버로 SQL 문 전달 후 결과를 DataTable 에 담기
                DataTable dtTemp = new DataTable();
                Adapter.Fill(dtTemp);

                // ID 와 PW 가 일치하지 않을 경우 (dtTemp 에 데이터가 한 건도 없을 경우)
                // return;
                if (dtTemp.Rows.Count == 0)
                {
                    MessageBox.Show("로그인 ID 가 잘못되었습니다.");
                    txtID.Text = "";
                    txtID.Focus();
                    ++iCount;
                    CheckThreeFail();
                    return;
                } // dtTemp 테이블에 받아온 데이터 중 PassWord 정보를 변수에 담는다.

                if (Convert.ToInt32(dtTemp.Rows[0]["PW_F_CNT"]) == 3)
                {
                    MessageBox.Show("3회 이상 비밀번호를 잘못입력하였습니다.\r\n 관리자와 문의 하세요.");
                    return;
                }

                // dtTemp 테이블에 받아온 데이터 중 PassWord 정보를 변수에 담는다.
                else if (sPassWord != Convert.ToString(dtTemp.Rows[0]["PW"]))
                {
                    MessageBox.Show("비밀번호를 잘못 입력하셨습니다.");
                    // 비밀번호 실패 횟수 증가
                    SqlTransaction Transaction = Connect.BeginTransaction("MyTran");
                    try
                    {
                        // 비밀번호 실패 횟수 변경
                        SqlCommand cmd = new SqlCommand();

                        // 비밀번호 누적 오류 횟수 tran
                        cmd.Transaction = Transaction;
                        cmd.Connection = Connect;
                        // 실행할 SQL 구문 등록 
                        string sUpdateSql;
                        sUpdateSql = " UPDATE TB_USER                          ";
                        sUpdateSql += $" SET PW_F_CNT = ISNULL(PW_F_CNT,0) + 1 ";
                        sUpdateSql += $" WHERE USERID = '{sLogInID}'           ";

                        // 커맨드에 실행할 SQL 구문 등록
                        cmd.CommandText = sUpdateSql;
                        // 커맨드 실행
                        cmd.ExecuteNonQuery();
                        // 정상 완료 시 COMMIT
                        Transaction.Commit();
                    }
                    catch
                    {
                        MessageBox.Show("누적 횟수 증가 오류 발생");
                        Transaction.Rollback();
                    }

                    // 비밀번호 누적 실패 횟수 확인 및 메세지
                    sFindUserSQL = " SELECT ISNULL(PW_F_CNT, 0) AS PWF_CNT";
                    sFindUserSQL += " FROM TB_USER ";
                    sFindUserSQL += $" WHERE USERID = '{sLogInID}'";

                    Adapter = new SqlDataAdapter(sFindUserSQL, Connect);

                    dtTemp = new DataTable();
                    Adapter.Fill(dtTemp);

                    if (Convert.ToInt32(dtTemp.Rows[0]["PW_F_CNT"]) == 3)
                    {
                        MessageBox.Show("3회 이상 비밀번호를 잘못 입력하셨습니다.");
                    }
                    return;
                }
                // ID 와 PW 가 일치할 경우 log in

                // 공통 변수에 값 대입
                Commons.sLogInUserID = sLogInID;
                Commons.sLogInUserName = Convert.ToString(dtTemp.Rows[0]["USERNAME"]);

                MessageBox.Show($"{Commons.sLogInUserName} 님 반갑습니다.");
                
                // 로그인이 성공했다는 값을 클래스의 Tag 에 등록
                this.Tag = true;

                this.Close();
            }
            catch (Exception ex)
            {

            }
            finally
            {
                Connect.Close();
            }
        }
        private void CheckThreeFail()
        {

        }

        private void btnPWChange_Click(object sender, EventArgs e)
        {
            M03_PassWordChange M03 = new M03_PassWordChange();
            this.Visible = false; // 로그인 화면을 숨기기
            M03.ShowDialog();
            this.Visible = true;
        }
    }
}

M03_PassWordChange.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// 데이터베이스 접속 라이브러리
using System.Data.SqlClient;

namespace MainForms
{
    /**********************************************************
     * NAME : M03_PassWordChange
     * DESC : 사용자 비밀번호 변경
     * --------------------------------------------------------
     * DATE        : 2022-06-21
     * AUTHOR      : 김유진
     * DESCRIPTION : 최초 프로그램 작성
     * ********************************************************/

    public partial class M03_PassWordChange : Form
    {
        // 1. 공통 클래스 (SELECT 와 Insert, Update, Delete 명령 전달 시 공통으로 사용)
        private SqlConnection Connect; // 데이터베이스 접속 정보 관리 클래스

        // 2. SELECT (조회) 를 실행 후 데이터를 받아오는 클래스
        private SqlDataAdapter Adapter;

        // 3. Insert, Delete, Update 를 실행할 명령 전달 클래스
        private SqlTransaction Transaction; // 데이터 관리 권한 부여 클래스
        private SqlCommand cmd;             // SQL 명령 전달 클래스

        public M03_PassWordChange()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            DoChangePassWord();
        }
        private void DoChangePassWord()
        {
            /**************************************************
             *               비밀번호 변경 클릭
             **************************************************/

            try
            {
                // 텍스트박스에 필수 입력값 등록 여부 확인
                string sMessage = string.Empty; // 메세지 변수
                if (txtUserID.Text == "")     sMessage = "사용자 ID";
                else if (txtOldPW.Text == "") sMessage = "이전 비밀번호";
                else if (txtNewPW.Text == "") sMessage = "변경 비밀번호";

                if (sMessage != "")
                {
                    MessageBox.Show(sMessage + "를 입력하지 않았습니다.");
                    return;
                }

                /*** 밸리데이션 체크 후 데이터 베이스 접속 ***/
                // 1. 데이터 베이스 접속 경로 설정
                string strConn = "Server = localhost ; Uid = sa ; Pwd = 1234 ; database = AppDev ;";

                // 2. 접속 경로 커넥터 객체에 전달
                Connect = new SqlConnection(strConn);

                // 3. 데이터베이스 연결 상태 확인
                Connect.Open(); // 데이터베이스 접속 시도
                if (Connect.State != ConnectionState.Open)
                {
                    MessageBox.Show("데이터베이스 연결에 실패하였습니다.");
                    return;
                }

                // 입력 내용 변수에 저장
                string sLogInID = txtUserID.Text; // 사용자 ID
                string sPerPassWord = txtOldPW.Text; // 현재 비밀번호
                string sNewPassWord = txtNewPW.Text; // 변경할 비밀번호

                #region < 기존 비밀번호와 비교하여 변경 가능한 상태인지 체크 >
                // 1. 기존 비밀번호 찾기 SQL 구문 작성
                string sFindUserInfo;
                sFindUserInfo  = " SELECT PW                   ";
                sFindUserInfo += "   FROM TB_USER              ";
                sFindUserInfo += $"  WHERE USERID = '{sLogInID}'";

                // 2. Adapter(SELECT 구문을 실행하고 결과를 받아오는 클래스)에 SQL 구문과 접속정보 등록
                Adapter = new SqlDataAdapter(sFindUserInfo, Connect);

                // 3. DataBase 로부터 결과 값을 받을 빈 DataTable 객체 생성
                DataTable dtTemp = new DataTable(); 

                // 4. Adapter 실행 및 결과 값 Datatable 에 등록
                Adapter.Fill(dtTemp);

                // 5. ID 존재 여부 확인
                if (dtTemp.Rows.Count == 0)
                {
                    MessageBox.Show("로그인 ID가 잘못되었습니다.");
                    return;
                }

                // 6. 현재 비밀번호 비교
                else if (sPerPassWord != Convert.ToString(dtTemp.Rows[0]["PW"]))
                {
                    MessageBox.Show("현재 비밀번호를 잘못 입력하였습니다.");
                    return;
                }

                if (MessageBox.Show("해당 비밀번호로 변경을 진행하시겠습니까?", "비밀번호 변경", MessageBoxButtons.YesNo) == DialogResult.No)
                    return;

                #endregion

                #region < 데이터베이스 명령 전달 클래스 객체에 설정한 SQL 문 등록 및 실행 > 
                // 1. 트랜잭션 선언 (데이터 관리 권한 부여)
                Transaction = Connect.BeginTransaction("MyTran");

                // 2. Insert, Update, Delete 명령을 전달할 SqlCommand 클래스 객체 생성
                cmd = new SqlCommand();

                // 3. 생성한 Command 에 트랜잭션 설정 정보 등록
                cmd.Transaction = Transaction;

                // 4. 접속 정보 등록
                cmd.Connection = Connect;

                // 5. 실행할 SQL 구문 등록
                string sUpdateSql;
                sUpdateSql  = " UPDATE TB_USER "                 ;
                sUpdateSql += $"   SET PW     = '{sNewPassWord}'";
                sUpdateSql += $" WHERE USERID = '{sLogInID}'"    ;

                // 6. 커맨드에 실행할 SQL 구문 등록
                cmd.CommandText = sUpdateSql;

                // 7. 커맨드 실행
                cmd.ExecuteNonQuery();

                // 8. 정상 완료 시 COMMIT
                Transaction.Commit();

                MessageBox.Show("비밀번호를 정상적으로 등록하였습니다.");
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show("비밀번호 등록 중 오류가 발생하였습니다. \r\n" + ex.ToString());
            }
            finally
            {
                Connect.Close();
            }
        }
    }
}

M04_MainForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// 스레드를 사용하기 위한 라이브러리 참조
using System.Threading;

namespace MainForms
{
    public partial class M04_MainForm : Form
    {
        private Thread thNowTime; // 현재 시각 스레드 객체
        public M04_MainForm()
        {
            InitializeComponent();
            M01_Login_N M01 = new M01_Login_N();
            M01.ShowDialog();
            // 호출했던 로그인 화면의 결과 Tag 값이 성공이 아니면 프로그램 종료
            if (Convert.ToBoolean(M01.Tag) != true)
            {
                Environment.Exit(0);

            }
        }
        // 신규 스레드를 통한 현재시간 체크
        // Thread : 프로세스 내부에서 생성되는 작업을 하는 주체
        //          스레드를 생성함으로서 하나의 프로세스 외에 여러 가지 일을 동시에 수행 가능
        private void M04_MainForm_Load(object sender, EventArgs e)
        {
            // 현재 시각 Thread 시작
            thNowTime = new Thread(new ThreadStart(GetNowTime));
            if (thNowTime.IsAlive == false) thNowTime.Start();
        }

        private void GetNowTime()
        {
            // 5초 뒤 스레드를 종료하기 위한 임시 변수
            int iThBreak = 0;
            while(true)
            {
                // 1초마다 갱신
                Thread.Sleep(1000);
                stsNowTime.Text = String.Format("{0:yyyy-M-dd HH:mm:ss}", DateTime.Now);
                iThBreak++;
                if (iThBreak == 5)
                    break;
            }
            MessageBox.Show("현재시각 표시 스레드를 종료합니다.");

            // 스레드의 종료
            thNowTime.Abort();
        }
        #region < 프로그램 종료 >
        private void tsExit_Click(object sender, EventArgs e)
        {
            // 프로그램 종료 버튼 클릭
            ApplicationExit();

        }

        private void M04_MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 메인화면 폼 종료 시
            ApplicationExit();
        }

        private void ApplicationExit()
        {
            // 확인메세지 표현 후 프로그램 종료
            if (MessageBox.Show("프로그램을 종료하시겠습니까?", "프로그램 종료", MessageBoxButtons.YesNo) == DialogResult.No) return;

            // 구동되고 있는 스레드 종료
            if (thNowTime.IsAlive) thNowTime.Abort();

            // 어플리케이션 종료
            Environment.Exit(0);
        }
        #endregion


        //private void timer1_Tick(object sender, EventArgs e)
        //{
        //    // 1틱이 발생될 때마다 (1초) 현재 일시를 라벨에 나타낸다.
        //    stsNowTime.Text = string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);
        //}
    }
}
LIST

'study' 카테고리의 다른 글

[C#] Log In  (0) 2022.06.20
[SQL] Exam (test)  (0) 2022.06.20
[SQL] Chapter 06. Insert Update Delete  (0) 2022.06.17
[SQL] Chapter 05. Index  (0) 2022.06.17
[SQL] Chapter 04. View  (0) 2022.06.16