[ad_1]
मैंने एसक्यूएल सर्वर डेटाबेस के साथ एक एप्लिकेशन विकसित किया है। मेरे पास व्यवस्थापक और सामान्य उपयोगकर्ता के साथ उपयोगकर्ता लॉगिन के लिए तालिका है। समस्या यह है कि जब मैं सामान्य उपयोगकर्ता के साथ लॉगिन करता हूं तो यह एडमिन के साथ-साथ सामान्य उपयोगकर्ता के लिए भी फॉर्म खोल देता है। संक्षेप में जब मैं सामान्य उपयोगकर्ता के साथ लॉगिन करता हूं तो यह दो फॉर्म खोलता है। कृपया सहायता करें।
मैंने क्या प्रयास किया है:
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(); } } } } }
समाधान 1
सबसे पहले आपको सबसे खराब समस्याओं से निपटना है, इसलिए मैं समझाऊंगा कि आपने आखिरी में क्या देखा।
1) SQL कमांड बनाने के लिए कभी भी स्ट्रिंग्स को संयोजित न करें। यह आपको आकस्मिक या जानबूझकर SQL इंजेक्शन हमले के लिए खुला छोड़ देता है जो आपके संपूर्ण डेटाबेस को नष्ट कर सकता है। इसके बजाय हमेशा पैरामीटरयुक्त क्वेरीज़ का उपयोग करें।
जब आप स्ट्रिंग्स को जोड़ते हैं, तो आप समस्याएँ पैदा करते हैं क्योंकि SQL को निम्न जैसे आदेश प्राप्त होते हैं:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
जहां तक एसक्यूएल का संबंध है, उपयोगकर्ता द्वारा जोड़ा गया उद्धरण स्ट्रिंग को समाप्त कर देता है और आपको समस्याएं आती हैं। लेकिन यह ज्यादा बुरा हो सकता है। अगर मैं साथ आता हूं और इसके बजाय इसे टाइप करता हूं: “x’; ड्रॉप टेबल मायटेबल; -” तो SQL को एक बहुत अलग कमांड प्राप्त होता है:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
कौन सा SQL तीन अलग-अलग कमांड के रूप में देखता है:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
एक पूर्णतया वैध चयन
DROP TABLE MyTable;
एक पूर्णतः मान्य “तालिका हटाएँ” आदेश
--'
और बाकी सब एक टिप्पणी है.
तो यह होता है: किसी भी मेल खाने वाली पंक्ति का चयन करता है, डीबी से तालिका हटा देता है, और किसी भी अन्य चीज़ को अनदेखा कर देता है।
इसलिए हमेशा पैरामीटरयुक्त प्रश्नों का उपयोग करें! या अपने DB को बार-बार बैकअप से पुनर्स्थापित करने के लिए तैयार रहें। आप नियमित रूप से बैकअप लेते हैं, है ना?
और लॉगिन स्क्रीन पर? यह निश्चित रूप से आत्मघाती है क्योंकि मुझे आपके डीबी को नष्ट करने के लिए उपयोगकर्ता होने की भी आवश्यकता नहीं है!
2) पासवर्ड को कभी भी स्पष्ट टेक्स्ट में संग्रहीत न करें – यह एक बड़ा सुरक्षा जोखिम है। इसे कैसे करें इस पर कुछ जानकारी यहां दी गई है: पासवर्ड संग्रहण: यह कैसे करें।[^]
और याद रखें: यदि आपके पास कोई यूरोपीय संघ उपयोगकर्ता है तो जीडीपीआर लागू होता है और इसका मतलब है कि आपको पासवर्ड को संवेदनशील डेटा के रूप में संभालने और उन्हें सुरक्षित तरीके से संग्रहीत करने की आवश्यकता है। पाठ उनमें से कुछ भी नहीं है और जुर्माना हो सकता है …. उम … बकाया। दिसंबर 2018 में एक जर्मन कंपनी को इसके लिए €20,000 का अपेक्षाकृत कम जुर्माना मिला।
3) आप यह जांच नहीं करते हैं कि डीबी ने कोई पंक्तियाँ लौटाई हैं या नहीं: यदि आप गलत टाइप करते हैं, तो यह “अनुक्रमणिका सीमा से बाहर” त्रुटि देगा और आपका ऐप क्रैश हो जाएगा।
4) आप केवल एडमिन के लिए कनेक्शन बंद करते हैं। कनेक्शन को मैन्युअल रूप से बंद करने के बजाय, पूरे DB कोड को घेर लें using
ब्लॉक और सिस्टम स्वचालित रूप से आपके लिए व्यवस्थित हो जाएगा।
5) आपने जो समस्या देखी है… अपना कोड देखें:
if (dt1.Rows[0][0].ToString() == "Admin") con.Close(); { Hide(); Admin ad = new Admin(); ad.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. }
[ad_2]
コメント