输错三次密码禁止登陆,15分钟后才能继续。

登录限制

Posted by JP on September 24, 2017

*登录限制

本文是用C#写的一个简单的登录案例,实现了用户输错三次密码禁止登陆,15分钟后才能继续。


先上布局:

这里写图片描述

项目思路:

  1. 分别用ErrorTimes、LastErrorDateTime字段记录登录错误次数和最后出错时间。
  2. 什么情况下允许登录?两种情况
    ①用户名对的前提下,输入密码的错误次数<=3次
    ②最后错误时间>15分钟
    不是这两种情况是不允许登录的。
  3. 第一步:先写下伪代码
    查询(select) 用户Id(UserId)、用户姓名(UserName)、用户密码(UserPwd)、输入错误次数(ErrorTimes)、最后出错时间(LastErrorDateTime )条件(where)UserName=txtUserName.Text.Trim() and UserPwd=txtUserPwd.Text.Trim()
    第二步:判断是否查询出数据
    ①如果没有数据:如果没有数据,用户名和密码不正确。增加一次错误次数,修改一下错误时间。
    ②如果有数据,说明用户名密码正确。那么进行后续判断
    ->校验时间是否符合规范,登陆次数是否满足。
    ->满足 ok
    ->不满足:提示。

用户登录记录表已经建好,表的定义和内容如下:

数据库表定义

数据库表内容


App.config配置文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <connectionStrings>
    <add name="sqlConn" connectionString="Data Source=.;Initial Catalog=SDBISAS;Persist Security Info=True;User ID=sa;Password=123456"/>
  </connectionStrings>
</configuration>

新建一个UserInfo的实体类,封装查询出来数据

    public class UserInfo
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string UserPwd { get; set; }
        public int ErrorTimes { get; set; }
        public DateTime LastErrorDateTime { get; set; }
    }

下面是此功能的核心代码

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace LoginLockDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private int infoError = 0;//定义用户登录错误次数的变量记录错误次数。
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(txtUserName.Text)&&string.IsNullOrEmpty(txtUserPwd.Text))
            {
                MessageBox.Show("用户名和密码不能为空!","提示",MessageBoxButton.OK,MessageBoxImage.Warning);
                return;
            }
            string sqlStr = ConfigurationManager.ConnectionStrings["sqlConn"].ConnectionString;
            using (SqlConnection conn = new SqlConnection(sqlStr))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    conn.Open();
                    cmd.CommandText = string.Format(@"select UserId,UserName,UserPwd,ErrorTimes,LastErrorDateTime from TabLoginRecord where UserName='{0}' and UserPwd='{1}'",txtUserName.Text.Trim(),txtUserPwd.Text.Trim());
                    UserInfo userInfo = null;//封装查询出来数据
                   
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())//如果有数据,说明有此用户,我们就把查询出来的数据赋值给UserInfo实体类
                        {
                            userInfo = new UserInfo();
                            userInfo.UserId = int.Parse(reader["UserId"].ToString());
                            userInfo.UserName = reader["UserName"].ToString();
                            userInfo.UserPwd = reader["UserPwd"].ToString();
                            userInfo.ErrorTimes = int.Parse(reader["ErrorTimes"].ToString());
                            userInfo.LastErrorDateTime = DateTime.Parse(reader["LastErrorDateTime"].ToString());
                        }
                    }//花括号执行结束前,连接一直没有关闭,这时候reader一直占用Connection对象
                    if (userInfo==null) //如果查询为空 说明用户名或密码不对 修改错误时间和次数 where UserName=txtUser.Text
                    {
                        infoError++;
                        //如果用户名和密码都不对也会执行下面的SQL脚本,占用服务器资源 所以加了一个全局变量记录用户和密码输入的次数
                        //如果用户名和密码都不对却输入十次以上,禁止直行SQL语句,结束。
                        if (infoError>10)
                        {
                            MessageBox.Show("登录错误次数太多了!歇歇吧!");
                            return;
                        }
                        cmd.CommandText = string.Format(@"update TabLoginRecord set ErrorTimes=ErrorTimes+1,LastErrorDateTime=getdate() where UserName='{0}'", txtUserName.Text.Trim());
                        cmd.ExecuteNonQuery();
                        MessageBox.Show("用户名或密码不正确!");
                        return;
                    }                
                    //有数据 校验时间和错误次数 
                    //当前的时间-最后一次错误的时间>15分钟
                    if (userInfo.ErrorTimes<=3||DateTime.Now.Subtract(userInfo.LastErrorDateTime).Minutes>15)
                    {
                        MessageBox.Show("登录成功");//错误次数清零
                        cmd.CommandText = string.Format(@"update TabLoginRecord set ErrorTimes=0 where UserName='{0}'",txtUserName.Text.Trim());
                        cmd.ExecuteNonQuery();
                    }
                    else
                    {
                        MessageBox.Show("登录失败!账号已被锁定!请15分钟后再试!");
                    }
                }
            }
        }
    }
}

好了,关于此功能今天就分析到这里,如有问题欢迎留言,大家共同学习。