하아찡

[C#/WPF] Login 프로젝트 Login 본문

C#/코인프로그램 - 코드

[C#/WPF] Login 프로젝트 Login

하아찡 2023. 12. 12. 22:01

로그인 기능 및 비회원 접속 기능.

비회원은 서버가 열려있을경우 하루 접속제한을 1회로 제한.

 

 

작업결과물

 

 

 

Login.xaml

<UserControl x:Class="CoinLogin.Views.Login"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"
             xmlns:tp="clr-namespace:TextBoxPlaceHolder;assembly=TextBoxPlaceHolder"
             Width="350" 
             prism:ViewModelLocator.AutoWireViewModel="True">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary  Source="pack://application:,,,/TextBoxplaceHolder;component/RTextBoxPlaceHolder.xaml" />
                <ResourceDictionary  Source="pack://application:,,,/TextBoxplaceHolder;component/RPasswordPlaceHolder.xaml" />
                <ResourceDictionary  Source="pack://application:,,,/CoinLogin;component/MyResource.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>

    </UserControl.Resources>

    <Border CornerRadius="15" BorderThickness="0" BorderBrush="Black" >
        <Border CornerRadius="10" BorderThickness="6">
            <Grid x:Name="MainGrid"  >
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*" />
                </Grid.RowDefinitions>
                <StackPanel VerticalAlignment="Center" Orientation="Vertical">
                    <TextBlock Text="로그인" Style="{StaticResource logintitleText}" Margin="0 0 0 20"/>
                    <tp:CTextBoxPlaceHolder Margin="0 0 0 10"  Style="{StaticResource ResourceKey=TextBoxPlaceHolder}" x:Name="TextBox" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="50"  TextValue="{Binding ID,Mode=TwoWay}"   PlaceHolder="ID"/>
                    <tp:CPasswordBoxPlaceHolder Margin="0 0 0 10"  Style="{StaticResource ResourceKey=PasswordPlaceHolder}" x:Name="CTextBox" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="50"   TextValue="{Binding PW,Mode=TwoWay}" PlaceHolder="PW"/>
                    <Button Margin="0 10 0 10" Style="{StaticResource ResourceKey=loginbutton}" Grid.Column="1" Command="{Binding CommandLoign}" Content="로그인" />
                    
                    <WrapPanel Margin="5" Grid.Column="0" HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Bottom">
                        <!--Button Style="{StaticResource ResourceKey=btnsub}" Content="비밀번호 찾기" Margin="0,0,5,0"  ></Button-->
                        <Button Style="{StaticResource ResourceKey=btnsub}" Command="{Binding CommandNonMember}" Content="비회원접속"></Button>
                    </WrapPanel>
                </StackPanel>

            </Grid>
        </Border>
        
    </Border>
    
</UserControl>

 

 

 

 

LoginViewModel.cs

using DB;
using Permission;
using Permission.Event;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Net;
using System.Windows;
using Upbit.Functions;

namespace CoinLogin.ViewModels
{
    public class LoginViewModel : BindableBase
    {
        #region Prism
        private IRegionManager _rm;
        private IEventAggregator _ea;
        private PM _pm;
        #endregion

        #region Model
        private string id;
        public string ID
        {
            get { return id; }
            set { SetProperty(ref id, value); }
        }

        private string pw;
        public string PW
        {
            get { return pw; }
            set { SetProperty(ref pw, value); }
        }
        #endregion Model

        #region Event
        private DelegateCommand commandlogin;
        public DelegateCommand CommandLoign =>
            commandlogin ?? (commandlogin = new DelegateCommand(ExecuteCommandLoign));

        void ExecuteCommandLoign()
        {
            if (Mssql.Instance.GetConnection() == false)
            {
                MessageBox.Show("서버가 닫혀있습니다. 비회원으로 이용해주세요.");
                return;
            }

            if ((ID == "" || PW == "" ) || (ID is null || PW is null))
            {
                MessageBox.Show("ID 또는 PW를 입력해 주세요");
                return;
            }
            bool IsLoginCheck = false;
            string query = $"SELECT * FROM ACCOUNT WHERE ID = '{ID}' AND PW = '{PW}'";
            int UserNumber = 0;
            SqlDataReader read = Mssql.Instance.ExecuteReaderQuery(query);
            if(read is not null)
            {
                string username = "";
                while (read.Read())
                {
                    username = read["USERNAME"].ToString();
                    UserNumber = Convert.ToInt32(read["NUMBER"]);
                    IsLoginCheck = true;

                }
                if (IsLoginCheck)
                {
                    //로그인 성공시 보냄
                    _pm.SetID(ID);
                    _pm.SetName(username);
                    _ea.GetEvent<MessageTitleEvent>().Publish($"{username}님 환영합니다.");
                    //사용 후 꼭 닫아줘야함
                    read.Close();

                    query = $"INSERT INTO ACCESSLOG(USERNUMBER, IP, KST) VALUES({UserNumber}, '{Network.Network.GetPublicIP()}', {FncDateTime.DateTimeToInt(DateTime.Now)})";
                    Mssql.Instance.ExecuteNonQuery(query);
                    _rm.RequestNavigate("Main", "Upbit");
                }
                else
                {
                    MessageBox.Show("등록된 계정이 없습니다.");
                }

            }
            else
            {
                MessageBox.Show("DB오류");
            }

        }

        private DelegateCommand commandnonmember;
        public DelegateCommand CommandNonMember =>
            commandnonmember ?? (commandnonmember = new DelegateCommand(ExecuteCommandNonMember));

        void ExecuteCommandNonMember()
        {
            //비회원 접속은 하루 1회로 제한, 단 서버가 닫혀있을땐 무제한으로 가능. 현재개인컴 서버라 OFF될일이 많음.



            if (Mssql.Instance.GetConnection())
            {
                string MyIP = Network.Network.GetPublicIP();
                DateTime time = DateTime.Now;
                time = time.AddHours(DateTime.Now.Hour * -1).AddMinutes(DateTime.Now.Minute * -1).AddSeconds(DateTime.Now.Second * -1);
                uint StartDay = FncDateTime.DateTimeToInt(time);
                uint EndDay = FncDateTime.DateTimeToInt(time.AddDays(1));

                string query = $"SELECT * FROM ACCESSLOG WHERE ({StartDay} <= KST AND KST < {EndDay}) AND IP ='{MyIP}'";

                bool IsNonMemberAccessCheck = Mssql.Instance.HasRows(query);    //접속기록 있을경우 true / 없을경우 false;
                if (IsNonMemberAccessCheck)
                {
                    //접속 불가
                    MessageBox.Show("비회원은 하루 최대 1회 접속가능합니다.");
                    return;
                }
                else
                {
                    //비회원 접속기록 보냄.
                    query = $"INSERT INTO ACCESSLOG(USERNUMBER, IP, KST) VALUES(0, '{MyIP}', {FncDateTime.DateTimeToInt(DateTime.Now)})";
                    Mssql.Instance.ExecuteNonQuery(query);
                }
            }
            _rm.RequestNavigate("Main", "Upbit");
            _ea.GetEvent<MessageTitleEvent>().Publish($"Upbit");



        }
        #endregion Event

        

        public LoginViewModel(IRegionManager rm, IEventAggregator ea, PM pm)
        {
            _rm = rm;
            _pm = pm;
            _ea = ea;
            PW = "";
        }
    }
}

 

 

 

비회원 접속 및 접속 1회제한

void ExecuteCommandNonMember()
{
    //비회원 접속은 하루 1회로 제한, 단 서버가 닫혀있을땐 무제한으로 가능. 현재개인컴 서버라 OFF될일이 많음.



    if (Mssql.Instance.GetConnection())
    {
        string MyIP = Network.Network.GetPublicIP();
        DateTime time = DateTime.Now;
        time = time.AddHours(DateTime.Now.Hour * -1).AddMinutes(DateTime.Now.Minute * -1).AddSeconds(DateTime.Now.Second * -1);
        uint StartDay = FncDateTime.DateTimeToInt(time);
        uint EndDay = FncDateTime.DateTimeToInt(time.AddDays(1));

        string query = $"SELECT * FROM ACCESSLOG WHERE ({StartDay} <= KST AND KST < {EndDay}) AND IP ='{MyIP}'";

        bool IsNonMemberAccessCheck = Mssql.Instance.HasRows(query);    //접속기록 있을경우 true / 없을경우 false;
        if (IsNonMemberAccessCheck)
        {
            //접속 불가
            MessageBox.Show("비회원은 하루 최대 1회 접속가능합니다.");
            return;
        }
        else
        {
            //비회원 접속기록 보냄.
            query = $"INSERT INTO ACCESSLOG(USERNUMBER, IP, KST) VALUES(0, '{MyIP}', {FncDateTime.DateTimeToInt(DateTime.Now)})";
            Mssql.Instance.ExecuteNonQuery(query);
        }
    }
    _rm.RequestNavigate("Main", "Upbit");
    _ea.GetEvent<MessageTitleEvent>().Publish($"Upbit");



}

 

DB서버가 닫혀있는지 체크해주는 함수를 호출 Mssql.Instance.GetConnection()

열려있을경우 True값으로 값을 받아와서 서버가 열려있으니 비회원은 해당 하루에 접속을 했을경우 접속을 못하게 처리.

먼저 쿼리를 보내 해당 아이피에 접속한 기록이 있는지를 확인하고 없을경우에 비회원으로 접속함과 동시에 해당 아이피로 접속했다는 정보를 DB에 기록함.

비회원은 USERNUMBER값은 0으로 고정하고 IP주소로 구분을 함.

해당 기능으로 제한 할 수 있는 이유는 UPBITAPI는 지정된 IP에서만 KEY값을 사용 할 수 있기때문에 해당 방식으로 처리함.

반응형