كيف يمكنني فتح اثنين مختلفين بناءً على حقوق المستخدم؟


لقد قمت بتطوير تطبيق باستخدام قاعدة بيانات SQL Server. لدي جدول لتسجيل دخول المستخدم مع المشرف والمستخدم العادي. المشكلة عندما أقوم بتسجيل الدخول باستخدام مستخدم عادي، فإنه يفتح النموذج للمسؤول وكذلك للمستخدم العادي. باختصار، يفتح نموذجين عندما أقوم بتسجيل الدخول باستخدام مستخدم عادي. الرجاء مساعدة.

ما حاولت:

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();
                    
                }
            }

            
            }

        }
    }

الحل 2

يبدو ذلك معقدًا للغاية بالنسبة لي. كل ما تحتاجه حقًا هو قراءة الصف الذي يطابق اسم المستخدم وكلمة المرور المحددين، وإرجاع نوع المستخدم. باستخدام هذه المعلومات، يمكنك بعد ذلك فتح نموذج المشرف أو المستخدم. يعد إنشاء اثنين من محولات البيانات وجداول البيانات فقط لقراءة صف واحد بمثابة إهدار للموارد إلى حد ما. شيء مثل:

ج#
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.
}

الحل 1

لديك أسوأ المشكلات التي يتعين عليك التعامل معها أولاً، لذا سأشرح لك ما لاحظته أخيرًا.

1) لا تقم أبدًا بتسلسل السلاسل لإنشاء أمر SQL. إنه يتركك مفتوحًا على مصراعيه لهجوم حقن SQL غير المقصود أو المتعمد والذي يمكن أن يدمر قاعدة البيانات بأكملها. استخدم دائمًا الاستعلامات ذات المعلمات بدلاً من ذلك.

عندما تقوم بتسلسل السلاسل، فإنك تسبب مشاكل لأن SQL يتلقى أوامر مثل:

SQL
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'

يؤدي الاقتباس الذي أضافه المستخدم إلى إنهاء السلسلة فيما يتعلق بـ SQL وستواجه مشاكل. ولكن يمكن أن يكون أسوأ. إذا أتيت وكتبت هذا بدلاً من ذلك: “x’;DROP TABLE MyTable;–” فسيتلقى SQL أمرًا مختلفًا تمامًا:

SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'

التي ترى SQL أنها ثلاثة أوامر منفصلة:

SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';

اختيار صالح تمامًا

SQL
DROP TABLE MyTable;

أمر “حذف الجدول” صالح تمامًا

SQL
--'

وكل شيء آخر هو تعليق.
وهكذا يحدث ذلك: تحديد أي صفوف متطابقة، وحذف الجدول من قاعدة البيانات، وتجاهل أي شيء آخر.

لذلك استخدم دائمًا الاستعلامات ذات المعلمات! أو كن مستعدًا لاستعادة قاعدة بياناتك من النسخة الاحتياطية بشكل متكرر. أنت تقوم بأخذ نسخ احتياطية بانتظام، أليس كذلك؟

وعلى شاشة تسجيل الدخول؟ يعد هذا أمرًا انتحاريًا إيجابيًا لأنني لست مضطرًا حتى إلى أن أكون مستخدمًا لتدمير قاعدة البيانات الخاصة بك!

2) لا تقم مطلقًا بتخزين كلمات المرور بنص واضح – فهذا يمثل خطرًا أمنيًا كبيرًا. هناك بعض المعلومات حول كيفية القيام بذلك هنا: تخزين كلمة المرور: كيفية القيام بذلك[^]

وتذكر: إذا كان لديك أي من مستخدمي الاتحاد الأوروبي، فسيتم تطبيق القانون العام لحماية البيانات (GDPR) وهذا يعني أنك بحاجة إلى التعامل مع كلمات المرور كبيانات حساسة وتخزينها بطريقة آمنة ومأمونة. النص ليس أيًا من هؤلاء ويمكن أن تكون الغرامات …. أم … معلقة. وفي ديسمبر 2018، تلقت شركة ألمانية غرامة منخفضة نسبيًا قدرها 20 ألف يورو بسبب ذلك.

3) لا تتحقق مما إذا كانت قاعدة البيانات قد أعادت أي صفوف: إذا أخطأت في الكتابة، فسوف يؤدي ذلك إلى ظهور خطأ “الفهرس خارج النطاق” وسيتعطل تطبيقك.

4) تقوم فقط بإغلاق الاتصال للمسؤولين. بدلاً من إغلاق الاتصال يدويًا، قم بإحاطة كود قاعدة البيانات بالكامل using الكتل وسيقوم النظام تلقائيًا بترتيبك.

5) المشكلة التي لاحظتها … انظر إلى الكود الخاص بك:

if (dt1.Rows[0][0].ToString() == "Admin")
    con.Close();
{
    Hide();
    Admin ad = new Admin();
    ad.Show();
}

إذا تطابق الشرط فإنه يغلق الاتصال. ثم يقوم دائمًا بتنفيذ التعليمات البرمجية الموجودة بين الأقواس المتعرجة حتى لو لم يتطابق الشرط …

コメント

タイトルとURLをコピーしました