功能简介
1、用户注册功能
要求:
1>不能重复注册,即用户名不能重复
2>密码必须八位
2、普通用户登录
可以进行的操作有:
1>文件上传(不可传相同文件名的文件)
2>文件下载(下载后会自动生成文件安全码提醒用户核对)
3>文件校验(生成下载的文件的安全码,提供给用户进行核对)
4>修改密码(修改前先验证用户身份,是否为非法用户,密码同样要求八位)
3、管理员登录
1>文件管理:可删除用户上传的文件
2>用户管理
a.查询所有用户,显示用户名和身份信息
b.对用户提权/降权,即提升为管理员或者降低为普通用户
c.删除某个用户,将其所有信息从数据库中删除
4、所有密码在数据库中以密文形式存
5、具有防止SQL注入的功能
注:4、5在功能演示中忘记演示,另附截图补充
实现过程
下面内容按照四个窗体分为为四个模块分别介绍
1、login.cs – 登陆界面
验证码
由一个lable控件实现,通过调用一个生成指定范围的随机字符作为lable.text显示,为了更有混淆效果,选择合适的背景图作陪衬。在窗体加载中调用生成验证码,也可以通过点击事件触发刷新。
public static string CreateRandomCode(int length) //生成由数字和大小写字母组成的验证码
{
string list = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
//list中存放着验证码的元素
Random random = new Random();
string code = ""; //验证码
for (int i = 0; i < length; i++) //循环6次得到一个伪随机的六位数验证码
{
code += list[random.Next(0, list.Length - 1)];
}
return code;
}
private void label4_Click(object sender, EventArgs e)
{
label4.Text = CreateRandomCode(4); //生成一个4位的验证码,并显示在标签lable上。
}
防SQL注入
利用SqlParameter对象传递参数执行SQL语句实现防注入
string sql = string.Format("select * from users where username = @username and password = @pwd and shenfen = '管理员'");
//创建SqlParameter对象,并设置参数值
SqlParameter param1 = new SqlParameter("username", username);
SqlParameter param2 = new SqlParameter("pwd", pwd);
//创建命令对象SqlCommand并添加参数
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
SqlDataReader reader = cmd.ExecuteReader();
2、regist.cs – 注册界面
MD5加密存储密码
实现极其简单,使用MD5加密对象,三行代码实现密码加密
//创建MD5加密对象
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
//把加密的数据转化为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(pwd1);
//对字节数组进行加密
bytes = md5.ComputeHash(bytes);
3、main.cs – 用户主要功能实现界面
文件上传
private void button4_Click(object sender, EventArgs e)
{
using (OpenFileDialog dialog = new OpenFileDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string src_path = dialog.FileName.ToString();
string filename = Path.GetFileName(src_path);
string dst = @"C:\Users\zxq\Desktop\上传";
string path = Path.Combine(dst, filename);
try
{
File.Copy(src_path, path);
MessageBox.Show(filename + "上传成功!");
}
catch (Exception)
{
MessageBox.Show("已存在该文件,请重命名后上传!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
}
}
}
文件下载
private void button3_Click(object sender, EventArgs e)
{
string name = textBox2.Text;
using (OpenFileDialog dialog = new OpenFileDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string src_path = dialog.FileName.ToString();
string filename = Path.GetFileName(src_path);
string dst = @"C:\Users\zxq\Desktop\下载";
string path = Path.Combine(dst, filename);
try
{
File.Copy(src_path, path);
MessageBox.Show(filename + "下载成功!");
}
catch (Exception)
{
MessageBox.Show("已存在该文件,请勿重复下载!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
}
String fileName = dialog.FileName;
this.textBox2.Text = "";
this.textBox2.Text = "请仔细核对下方安全码确保文件没有被篡改";
this.textBox1.Text = "";
this.textBox1.Text = getMD5Hash(fileName);
}
}
计算文件MD5码
//计算文件的MD5码
private string getMD5Hash(string pathName)
{
string strResult = "";
string strHashData = "";
byte[] arrbytHashValue;
System.IO.FileStream oFileStream = null;
System.Security.Cryptography.MD5CryptoServiceProvider oMD5Hasher = new System.Security.Cryptography.MD5CryptoServiceProvider();
try
{
oFileStream = new System.IO.FileStream(pathName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
arrbytHashValue = oMD5Hasher.ComputeHash(oFileStream);//计算指定Stream 对象的哈希值
oFileStream.Close();
//由以连字符分隔的十六进制对构成的String,其中每一对表示value 中对应的元素;例如“F-2C-4A”
strHashData = System.BitConverter.ToString(arrbytHashValue);
//替换-
strHashData = strHashData.Replace("-", "");
strResult = strHashData;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
return strResult;
}
实时显示时间(为了好玩)
先在main.cs窗体添加一个Timer组件,在main_load()方法里面添加如下两行代码:
timer1.Interval = 1000;//用于设置调用XXX_Tick时间的毫秒数
timer1.Start();
然后在timer1_Tick()中分两次分别获取当前年月日和时分秒,在窗体中添加两个文本框用来接收显示时间即可。
private void timer1_Tick(object sender, EventArgs e)
{
//string time1 = DateTime.Now.ToShortDateString().ToString(); //2020 - 6 - 27
//string time2 = DateTime.Now.ToLongTimeString().ToString(); // 18:02:12
this.label4.Text = DateTime.Now.ToShortDateString().ToString();
this.label5.Text = DateTime.Now.ToLongTimeString().ToString();
}
4、zxq.cs – 管理员界面
一键查询功能
private void button5_Click(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ToString()))
{
SqlDataAdapter sda = new SqlDataAdapter("Select username,shenfen From users", conn);
DataSet Ds = new DataSet();
sda.Fill(Ds, "T_Class");
//使用DataSet绑定时,必须同时指明DateMember
this.dataGridView1.DataSource = Ds;
this.dataGridView1.DataMember = "T_Class";
//也可以直接用DataTable来绑定
this.dataGridView1.Visible = true;
this.dataGridView1.DataSource = Ds.Tables["T_Class"];
}
}
用户删除和提权降权功能均是对数据库内容的修改,以降权为例
private void button3_Click_1(object sender, EventArgs e)
{
string username = this.textBox1.Text;
string conStr = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
SqlConnection conn = new SqlConnection(conStr);
conn.Open();
string sql = string.Format("update users set shenfen = '普通用户' where username = @username");
SqlParameter param1 = new SqlParameter("username", username);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add(param1);
cmd.Connection = conn;
cmd.CommandText = sql;
try
{
int r = cmd.ExecuteNonQuery();
if (r == 1)
{
MessageBox.Show("降权成功!");
}
else
{
MessageBox.Show("查无此人,请核对名称重试!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
catch (Exception)
{
MessageBox.Show("操作失败,请重试!");
}
}
功能演示
https://www.bilibili.com/video/BV135411e7mq/
[video(video-8MhPcQwP-1594113014999)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=456337151)(image-https://img-blog.csdnimg.cn/img_convert/1e4b203275299477524ab6397bf0a741.png)(title- )]
防注入