study
[C#] Log In 02
yz
2022. 6. 21. 14:57
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