接着 上篇文章所谈到的系统缺陷,这篇文章进行升级解决。
问题:注册界面与登录界面是同一个界面,导致用户输入用户密码进行注册后,即可点击登录。
解决:在同一个场景中分别创建注册界面和登录界面,使用SetActive控制注册/登录成功后UI的显示与隐藏。
整体的UI框架搭建如下图所示:
其中,底下蓝色的文字作为提示信息提示用户的注册情况。
其中,底下紫色的文字作为提示信息提示用户的注册情况。
由于这里注册与登录使用的是同一个输入框,因此在登录或注册后对输入框清空。这里还需要注意一点,需要判断登录和注册时用户名密码是否为空,如果为空,给出不能为空的提示。
交互功能代码:
using UnityEngine; using UnityEngine.UI; using MySql.Data.MySqlClient; using System; public class DatabaseManager : MonoBehaviour { // 数据库连接相关变量 private MySqlConnection connection; private string serverName = "localhost"; private string dbName = "UnityGame"; // 数据库名 private string userName = "root"; // 登录数据库的用户名 private string password = "123456"; // 登录数据库的密码 private string port = "3306"; // MySQL服务的端口号 // 注册UI和登录UI public GameObject RegisterUI; public GameObject LoginUI; // 用户名输入框和密码输入框 public InputField usernameInputField; public InputField passwordInputfield; // 注册消息和登录消息 public Text registerMessage; public Text loginMessage; void Start() { // 初始化UI状态 LoginUI.SetActive(true); RegisterUI.SetActive(false); // 连接数据库 string connectionString = "Server=" + serverName + ";Database=" + dbName + ";Uid=" + userName + ";Pwd=" + password + ";Port=" + port + ";"; connection = new MySqlConnection(connectionString); connection.Open(); Debug.Log("连接数据库成功"); } // 注册逻辑 public void OnRegister() { // 从输入框获取用户名和密码 string username = usernameInputField.text; string password = passwordInputfield.text; if (username == "" || password == "") { registerMessage.text = "账号或密码不能为空"; } else { // 构造插入数据的SQL语句,并将用户名和密码赋值给参数 string query = "INSERT INTO usersinfo(username, password) VALUES (@username, @password)"; MySqlCommand cmd = new MySqlCommand(query, connection); cmd.Parameters.AddWithValue("@username", username); cmd.Parameters.AddWithValue("@password", password); // 执行SQL语句,获取影响的行数 int rowsAffected = cmd.ExecuteNonQuery(); // 根据影响的行数给出注册成功或失败的消息,并清空输入框 if (rowsAffected > 0) { Debug.Log("注册成功"); registerMessage.text = "注册成功"; } else { Debug.Log("注册失败"); registerMessage.text = "注册失败"; } usernameInputField.text = ""; passwordInputfield.text = ""; } } // 登录逻辑 public void OnLogin() { // 从输入框获取用户名和密码 string username = usernameInputField.text; string password = passwordInputfield.text; if(username == "" || password == "") { loginMessage.text = "账号或密码不能为空"; } else { // 构造查询数据的SQL语句,并将用户名和密码赋值给参数 string query = "SELECT COUNT(*) FROM usersinfo WHERE username=@username AND password=@password"; MySqlCommand cmd = new MySqlCommand(query, connection); cmd.Parameters.AddWithValue("@username", username); cmd.Parameters.AddWithValue("@password", password); // 执行SQL语句,获取查询结果 object result = cmd.ExecuteScalar(); int count = Convert.ToInt32(result); // 根据影响的行数给出注册成功或失败的消息,并清空输入框 if (count > 0) { Debug.Log("登录成功"); loginMessage.text = "登录成功"; } else { Debug.Log("登录失败"); loginMessage.text = "登录失败"; } usernameInputField.text = ""; passwordInputfield.text = ""; } } }
相关变量绑定:
去注册的按钮事件绑定:
去登录的按钮事件绑定:
问题1:用户注册时没有对用户信息进行校验,如一个用户用同一个用户名进行注册时应该进行提示、用户名或密码为空也应该进行提示。
问题2:用户注册时的注册时间没有加入用户表。
问题3:用户注册时输入的密码以明文存储于数据库中,这是不安全的。
使用SQL查询语句查询数据库中是否存在具有给定用户名的用户记录,检查查询结果并根据需要返回检查用户输入的信息。如果 count 变量的值为0,则表示数据库中不存在具有该用户名的用户记录,可以继续进行注册流程。如果 count 变量的值大于0,则表示该用户名已经被占用,需要提示用户选择不同的用户名。
修改后的注册功能的代码实现:
// 注册逻辑 public void OnRegister() { // 从输入框获取用户名和密码 string username = usernameInputField.text; string password = passwordInputfield.text; if (username == "" || password == "") { registerMessage.text = "账号或密码不能为空"; } else { // 检查数据库中是否存在具有给定用户名的用户记录 string query1 = "SELECT COUNT(*) FROM usersinfo WHERE username = @Username"; MySqlCommand cmd1 = new MySqlCommand(query1, connection); cmd1.Parameters.AddWithValue("@Username", username); int count = Convert.ToInt32(cmd1.ExecuteScalar()); // 根据查询结果提示用户 if (count > 0) { Debug.Log("用户名已存在,请选择不同的用户名!"); registerMessage.text = "用户名已存在,请选择不同的用户名!"; } else { // 构造插入数据的SQL语句,并将用户名和密码赋值给参数 string query2 = "INSERT INTO usersinfo(username, password) VALUES (@username, @password)"; MySqlCommand cmd2 = new MySqlCommand(query2, connection); cmd2.Parameters.AddWithValue("@username", username); cmd2.Parameters.AddWithValue("@password", password); // 执行SQL语句,获取影响的行数 int rowsAffected = cmd2.ExecuteNonQuery(); // 根据影响的行数给出注册成功或失败的消息 if (rowsAffected > 0) { Debug.Log("注册成功"); registerMessage.text = "注册成功"; } else { Debug.Log("注册失败"); registerMessage.text = "注册失败"; } } //清空输入框 usernameInputField.text = ""; passwordInputfield.text = ""; } }
将usersinfo的createtime列类型设置为timestamp,并将其默认值修改为CURRENT_TIMESTAMP。
注册成功后插入数据库的结果:
在C#脚本中对用户注册和登录的结果都使用哈希进行加密,这样在进行比较时,都是使用加密后的密文进行比较的。
修改的部分代码:
using System.Security.Cryptography; // 加密密码 private static string HashPassword(string password) { SHA256Managed crypt = new SHA256Managed(); StringBuilder hash = new StringBuilder(); byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(password)); foreach (byte theByte in crypto) { hash.Append(theByte.ToString("x2")); } return hash.ToString(); } // 注册逻辑 public void OnRegister() { // 从输入框获取用户名和密码 string username = usernameInputField.text; //使用哈希进行加密 string password = HashPassword(passwordInputfield.text); //省略 } // 登录逻辑 public void OnLogin() { // 从输入框获取用户名和密码 string username = usernameInputField.text; //使用哈希进行加密 string password = HashPassword(passwordInputfield.text); //省略 }
其中,加入了关闭数据库,用户登录成功后关闭数据库。
注册成功后插入数据库的结果:
问题:用户登录时,没有针对特定错误进行提示,不论是因用户名密码错误还是该用户未注册都是提示“登录失败”。
修改后的登录功能的代码实现:
// 登录逻辑 public void OnLogin() { // 从输入框获取用户名和密码 string username = usernameInputField.text; //使用哈希进行加密 string password = HashPassword(passwordInputfield.text); if (username == "" || password == "") { loginMessage.text = "账号或密码不能为空"; } else { // 构造查询数据的SQL语句,并将用户名和密码赋值给参数 string query = "SELECT COUNT(*) FROM usersinfo WHERE username=@username AND password=@password"; MySqlCommand cmd = new MySqlCommand(query, connection); cmd.Parameters.AddWithValue("@username", username); cmd.Parameters.AddWithValue("@password", password); // 执行SQL语句,获取查询结果 object result = cmd.ExecuteScalar(); int count = Convert.ToInt32(result); // 根据影响的行数给出注册成功或失败的消息,并清空输入框 if (count > 0) { Debug.Log("登录成功"); loginMessage.text = "登录成功"; } else { // 根据查询结果给出不同的提示消息 string errorMessage; query = "SELECT COUNT(*) FROM usersinfo WHERE username=@username"; cmd = new MySqlCommand(query, connection); cmd.Parameters.AddWithValue("@username", username); result = cmd.ExecuteScalar(); count = Convert.ToInt32(result); if (count == 0) { errorMessage = "用户名不存在"; } else { errorMessage = "密码错误"; } Debug.Log("登录失败:" + errorMessage); loginMessage.text = errorMessage; } usernameInputField.text = ""; passwordInputfield.text = ""; } }
填写用户名密码登录→用户名不存在→去注册→填写用户名密码注册→注册成功:
用同样的用户名注册→用户名已存在→去登录→输入其他用户名→用户名不存在→输入正确用户名错误密码→密码错误→输入正确用户名正确密码→登录成功:
UsersInfo数据表中的数据:
【Unity+MySQL】实现简单的注册登录系统
【Unity+MySQL】实现注册登录系统(升级版)
【Unity+MySQL】实现注册登录系统(封装版)
上一篇:17 Go的文件操作