【解決方法】ユーザー権限に基づいて 2 つの異なるファイルを開くにはどうすればよいですか?


SQLサーバーデータベースを使用してアプリケーションを開発しました。 管理者と通常のユーザーによるユーザーログイン用のテーブルがあります。 通常のユーザーでログインすると、通常のユーザーだけでなく管理者用のフォームも開きます。 つまり、通常のユーザーでログインすると 2 つのフォームが開きます。 手伝ってください。

私が試したこと:

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 が次のようなコマンドを受け取るため、問題が発生します。

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 では、次の 3 つの個別のコマンドとして認識されます。

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

完全に有効な SELECT

SQL
DROP TABLE MyTable;

完全に有効な「テーブルの削除」コマンド

SQL
--'

それ以外はすべてコメントです。
つまり、一致する行を選択し、DB からテーブルを削除し、それ以外は無視します。

したがって、常にパラメータ化されたクエリを使用してください。 または、DB をバックアップから頻繁に復元できるように準備してください。 バックアップは定期的に取っていますよね?

そしてログイン画面では? DB を破壊するのにユーザーである必要さえないので、これは明らかに自殺行為です。

2) パスワードをクリア テキストで保存しないでください。これは重大なセキュリティ リスクです。 その方法については、ここにいくつかの情報があります。 パスワードの保管: その方法。[^]

覚えておいてください。欧州連合のユーザーがいる場合は GDPR が適用されるため、パスワードを機密データとして扱い、安全な方法で保存する必要があります。 テキストはそのどちらでもないので、罰金は …. うーん … 未払いになる可能性があります。 2018年12月、ドイツの企業はそれだけの理由で2万ユーロという比較的低額の罰金を科せられた。

3) DB が行を返したかどうかはチェックしません。入力を間違えると、「インデックスが範囲外です」エラーがスローされ、アプリがクラッシュします。

4) 管理者の接続のみを閉じます。 接続を手動で閉じる代わりに、DB コード全体を次のように囲みます。 using ブロックすると、システムが自動的に整理してくれます。

5) あなたが気づいた問題 … コードを見てください。

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

条件が一致すると、接続が閉じられます。その後、条件が一致しなかった場合でも、常に中括弧内のコードが実行されます。

解決策 2

それは私には非常に複雑に思えます。 本当に必要なのは、指定されたユーザー名とパスワードに一致する行を読み取り、ユーザー タイプを返すことだけです。 その情報を使用して、管理フォームまたはユーザー フォームを開くことができます。 1 行を読み取るためだけに 2 つのデータアダプターとデータテーブルを作成すると、リソースが多少無駄になります。 何かのようなもの:

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

コメント

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