[ad_1]
Tôi đã phát triển một ứng dụng với cơ sở dữ liệu máy chủ sql. Tôi có bảng để người dùng đăng nhập với quản trị viên và người dùng bình thường. Vấn đề khi tôi đăng nhập với người dùng bình thường, nó mở biểu mẫu cho Quản trị viên cũng như người dùng bình thường. Nói tóm lại, nó sẽ mở hai biểu mẫu khi tôi đăng nhập với người dùng bình thường. Xin vui lòng giúp đỡ.
Những gì tôi đã thử:
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 Stokvel_Management_System { public partial class Login : Form { public Login() { InitializeComponent(); } public string constring = "Data Source=LAPTOP-TINYIKOB\\SQLEXPRESS;Initial Catalog=Stokvel;Integrated Security=True"; private void BtnLogin_Click(object sender, EventArgs e) { SqlConnection con = new SqlConnection(constring); con.Open(); SqlDataAdapter da = new SqlDataAdapter("select count(*) from loginTab where UserName='" + txtUsername.Text + "' and Password='" + txtPassword.Text + "'and Type='" + UsercomboBox.Text + "'", con); DataTable dt = new DataTable(); da.Fill(dt); if (dt.Rows[0][0].ToString() == "1") { SqlDataAdapter da1 = new SqlDataAdapter("select Type from loginTab where UserName='" + txtUsername.Text + "' and Password='" + txtPassword.Text + "'", con); DataTable dt1 = new DataTable(); da1.Fill(dt1); if (dt1.Rows[0][0].ToString() == "Admin") con.Close(); { Hide(); Admin ad = new Admin(); ad.Show(); } if(dt1.Rows[0][0].ToString()=="User") { Hide(); User us = new User(); us.Show(); } } } } }
Giải pháp 1
Bạn có những vấn đề tồi tệ nhất cần giải quyết trước, vì vậy tôi sẽ giải thích điều bạn nhận thấy sau cùng.
1) Không bao giờ nối các chuỗi để tạo lệnh SQL. Nó khiến bạn có nguy cơ bị tấn công SQL SQL vô tình hoặc cố ý, có thể phá hủy toàn bộ cơ sở dữ liệu của bạn. Thay vào đó, hãy luôn sử dụng các truy vấn được tham số hóa.
Khi bạn nối các chuỗi, bạn sẽ gặp vấn đề vì SQL nhận được các lệnh như:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Trích dẫn mà người dùng đã thêm sẽ chấm dứt chuỗi liên quan đến SQL và bạn gặp vấn đề. Nhưng nó có thể tồi tệ hơn. Thay vào đó, nếu tôi gõ cái này: “x’;DROP TABLE MyTable;–” thì SQL sẽ nhận được một lệnh rất khác:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
SQL nào được coi là ba lệnh riêng biệt:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
CHỌN hoàn toàn hợp lệ
DROP TABLE MyTable;
Lệnh “xóa bảng” hoàn toàn hợp lệ
--'
Và mọi thứ khác là một bình luận.
Đúng như vậy: chọn bất kỳ hàng phù hợp nào, xóa bảng khỏi DB và bỏ qua mọi thứ khác.
Vì vậy, LUÔN LUÔN sử dụng các truy vấn được tham số hóa! Hoặc hãy sẵn sàng khôi phục DB của bạn từ bản sao lưu thường xuyên. Bạn có sao lưu thường xuyên phải không?
Và trên MÀN HÌNH ĐĂNG NHẬP? Điều đó chắc chắn là tự sát vì tôi thậm chí không cần phải là người dùng mới có thể phá hủy DB của bạn!
2) Không bao giờ lưu trữ mật khẩu ở dạng văn bản rõ ràng – đó là một rủi ro bảo mật lớn. Có một số thông tin về cách thực hiện ở đây: Lưu trữ mật khẩu: Cách thực hiện.[^]
Và hãy nhớ: nếu bạn có bất kỳ người dùng nào ở Liên minh Châu Âu thì GDPR sẽ được áp dụng và điều đó có nghĩa là bạn cần xử lý mật khẩu dưới dạng dữ liệu nhạy cảm và lưu trữ chúng một cách an toàn và bảo mật. Văn bản không phải là những thứ đó và tiền phạt có thể là …. ừm … chưa thanh toán. Vào tháng 12 năm 2018, một công ty Đức đã nhận được mức phạt tương đối thấp là 20.000 euro chỉ vì hành vi đó.
3) Bạn không kiểm tra xem DB có trả về bất kỳ hàng nào không: nếu bạn nhập sai, nó sẽ đưa ra lỗi “chỉ mục nằm ngoài phạm vi” và ứng dụng của bạn sẽ bị lỗi.
4) Bạn chỉ đóng kết nối đối với Quản trị viên. Thay vì đóng kết nối theo cách thủ công, hãy bao quanh toàn bộ mã DB trong using
các khối và hệ thống sẽ tự động dọn dẹp cho bạn.
5) Vấn đề bạn nhận thấy … Hãy xem mã của bạn:
if (dt1.Rows[0][0].ToString() == "Admin") con.Close(); { Hide(); Admin ad = new Admin(); ad.Show(); }
Nếu điều kiện phù hợp, nó sẽ đóng kết nối. Sau đó, nó luôn thực thi mã trong dấu ngoặc nhọn ngay cả khi điều kiện không khớp …
Giải pháp 2
Điều đó có vẻ quá phức tạp đối với tôi. Tất cả những gì bạn thực sự cần là đọc hàng khớp với tên người dùng và mật khẩu đã cho và trả về loại người dùng. Với thông tin đó, bạn có thể mở biểu mẫu quản trị viên hoặc người dùng. Việc tạo hai bộ điều hợp dữ liệu và bảng dữ liệu chỉ để đọc một hàng có phần lãng phí tài nguyên. Cái gì đó như:
string queryString = "select Type from loginTab where UserName='" + txtUsername.Text + "' and Password='" + txtPassword.Text + "'"; string usertype = "None"; using (SqlConnection connection = new SqlConnection( connectionString)) { SqlCommand command = new SqlCommand( queryString, connection); connection.Open(); using(SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { usertype = reader[0]; // returned value } } } if (usertype == "Admin") { Hide(); Admin ad = new Admin(); ad.Show(); } else if(usertype == "User") { Hide(); User us = new User(); us.Show(); } else { // invalid type, or no matching record. }
[ad_2]
コメント