2011-03-15 2 views
2

두 가지 액세스 레벨을 갖는 로그인 시스템을 만들려고합니다. 액세스 레벨이 1이면 'carer 홈 페이지'를 수신하고, 레벨이 2이면 '관리자 페이지'를 수신합니다. 로그인 양식에는 사용자가 버튼을 클릭하고 tryLogin 변수가 true를 반환 할 때 데이터베이스의 자격 증명에 대해 사용자 이름과 암호의 유효성을 검사하는 변수가 있습니다. 데이터베이스의 사용자 이름이 사용자 이름 텍스트와 일치하는 데이터베이스에서 액세스 수준을 가져옵니다 field두 개의 액세스 레벨을 가진 로그인 시스템

양식을로드하는 대신 잘못된 로그인 자격 증명이 표시됩니다. 필자는 이것에 대해 오랜 시간을 보냈으며 잃어 버렸습니다. 문제가 충분히 설명되기를 바랍니다.

public bool tryLogin(string uname, string pword) 
     { 
      MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";"); 
      MySqlCommand cmd = new MySqlCommand("SELECT * FROM Staff WHERE username = '" + uname + "' AND password ='" + pword + "';"); 
      cmd.Connection = con; 
      con.Open(); 
      MySqlDataReader reader = cmd.ExecuteReader(); 



      if (reader.Read() != false) 
      { 
       if (reader.IsDBNull(0) == true) 
       { 
        cmd.Connection.Close(); 
        reader.Dispose(); 
        cmd.Dispose(); 
        return false; 
       } 
       else 
       { 
        cmd.Connection.Close(); 
        reader.Dispose(); 
        cmd.Dispose(); 
        return true; 
       } 
      } 
      else 
      { 

       return false; 

      } 
     } 



private void LoginBT_Click(object sender, EventArgs e) 
     { 


      if (tryLogin(uname.Text, pword.Text) == true) 
      { 
       MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";"); 
       MySqlCommand cmd2 = new MySqlCommand("SELECT access_level FROM Staff WHERE username = '" + uname + "';"); 

       cmd2.Connection = con; 
       con.Open(); 


       MySqlDataReader reader = cmd2.ExecuteReader(); 

       if (cmd2.Equals("1")) 

       { 
        this.Hide(); 
        CarerHomePage CarerHomePage = new CarerHomePage(); 
        CarerHomePage.Show(); 
       } 

       if (cmd2.Equals("2")) 
       { 
        this.Hide(); 
        AdministratorHome AdministratorHome = new AdministratorHome(); 
        AdministratorHome.Show(); 

       } 


       else 
       { 
        MessageBox.Show("Invalid Login Credentials"); 
       } 



      } 

     } 

    } 
} 
+7

! [SQL 주입] (http://en.wikipedia.org/wiki/SQL_injection) 취약점이 많이 있습니다. [작은 바비 테이블] (http://xkcd.com/327/)에 대해 들어 보지 못했습니까? – Cameron

+0

@Cameron : lmao. – Paul

+1

"오랫동안이 작업을 해왔습니다."는 말은 아마도 디버거를 사용하고 있지 않은 것입니다. Visual Studio의 도움없이이 글을 쓰고 있습니까? 그렇다면 C#으로 더 편하게 프로그래밍 할 때까지 [Visual Studio Express] (http://www.microsoft.com/express/)를 사용하는 것이 좋습니다. –

답변

1

개선의 여지가 많이 있습니다 만, 무엇이 잘못 되었습니까? 난 당신이 의미 생각

MySqlDataReader reader = cmd2.ExecuteReader(); 
if (cmd2.Equals("1")) // What the fail? 

:

당신이 바쁜 유지하는 것 문제는 당신이 명령 자체와 SQL 명령의 실행 결과를 비교 있다는 것입니다

object accessCode = cmd2.ExecuteScalar(); 
if (accessCode != null && accessCode != DBNull.Value) 
{ 
    if (accessCode.ToString() == "1") 
    { 
     this.Hide(); 
     CarerHomePage CarerHomePage = new CarerHomePage(); 
     CarerHomePage.Show(); 
    } 
3

SQL 인젝션에 대해 알아야합니다. 당신은 또한 asp.net 사용자 관리/역할에 내장에 대한 책을 읽은 고려해야 사용자 이름 텍스트 상자에

및 로그인을 시도 - -. 텍스트

'OR = 1 : 1을 추가하는 시도는 비트 역할입니다 여기에서 당신을 잘 섬길 것입니다. 여기 ScottGu에서

좋은 링크 :

http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx

+0

우수한 점이 있지만 직접 질문에 대답하지는 않습니다. 아아아, 여기에는 +1이 없지만 이것을 말하는 것은 분명 중요하고 중요합니다. :) – Chris

+1

@Chris - 처음에는 임의의 '2 단계 로그인'시스템을 사용하는 것이 누군가가 요구할 때 시스템을 더 이상 확장하지 못하는 것입니다. 일부 관리 기능에 액세스 할 수있는 보호자 사용자입니다. 역할 기반 인증은 시작부터 훨씬 더 나은 방법입니다. – Paddy

+1

Paddy와 확실히 동의합니다. 자신이하는 일을 정말로 알기 전까지는 자신의 것을 긁어 모으지 않고 입증 된 보안 프레임 워크를 사용하는 것이 가장 좋습니다. –

3

문제는 당신이 stringcmd2 (ExecuteReader의 인스턴스)를 비교하는 것 같다. 왜 이것이 사실일까요? 쿼리 결과 대신 쿼리 결과를 문자열로 검사해야합니다.

If if 문에는 CarrerHomePage가로드되어 있어도 메시지 상자가 표시됩니다. 다음과 같이 시도하십시오.

  if (cmd2.Equals("1")) 
      { 
       this.Hide(); 
       CarerHomePage CarerHomePage = new CarerHomePage(); 
       CarerHomePage.Show(); 
      } 
      else if (cmd2.Equals("2")) 
      { 
       this.Hide(); 
       AdministratorHome AdministratorHome = new AdministratorHome(); 
       AdministratorHome.Show(); 

      } 
      else 
      { 
       MessageBox.Show("Invalid Login Credentials"); 
      } 
+0

아, 맞았다. 네가 내가 생각했던 것보다 훨씬 더 좋은 점들을 만들었지 만 너는 나도 어리석은 짓을 그만 두었다. ;-) – Chris

1

네, 여기에 많은 문제가 있습니다. 항상 매개 변수가있는 쿼리를 사용해야합니다.

문제는 DataReader를 사용하여 결과 행을 검색하는 대신 cmd.Equals를 사용하고 있다는 것입니다.

단일 값을 검색하려는 경우 ExecuteScalar를 사용할 수 있습니다. MySqlCommand에서 Doc을 꽤 철저히 읽는 것이 좋습니다.

마지막으로 블록을 사용하여 개체를 래핑 할 수 있습니다. 이렇게하면 자동으로 옵션이 닫히고 처분됩니다. 코드를 단축합니다

public bool tryLogin(string uname, string pword) 
{ 
    using(MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";")) 
    using(MySqlCommand cmd = new MySqlCommand("SELECT * FROM Staff WHERE username = @name AND password = @pwd;")) 
    { 
     cmd.Parameters.AddWithValue("@name", uname); 
     cmd.Parameters.AddWithValue("@pwd", pword); 
     cmd.Connection = con; 
     cmd.Connection.Open();    
     using(var reader = cmd.ExecuteReader()) 
     { 
      return reader.Read() && !reader.IsDBNull(0));     
     } 
    } 
} 



private void LoginBT_Click(object sender, EventArgs e) 
{ 
    if (tryLogin(uname.Text, pword.Text)) 
    { 
     using(MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";")) 
     using(MySqlCommand cmd2 = new MySqlCommand("SELECT access_level FROM Staff WHERE username = '" + uname + "';")) 
     { 
      cmd2.Connection = con; 
      cmd2.Connection.Open();     

      using(MySqlDataReader reader = cmd2.ExecuteReader()) 
      { 
       if(reader.Read()) 
       { 
        var accessLevel = reader.GetInt32("access_level"); 
        switch(accessLevel) 
        { 
         case 1: 
          this.Hide(); 
          CarerHomePage CarerHomePage = new CarerHomePage(); 
          CarerHomePage.Show(); 
          break; 
         case 2: 
          this.Hide(); 
          AdministratorHome AdministratorHome = new AdministratorHome(); 
          AdministratorHome.Show(); 
          break; 
         default: 
          MessageBox.Show("Invalid Login Credentials"); 
          break; 
        } 
       } 
      } 
     } 
    } 

} 
0

확인, 로그인 시도 bool 제대로 작동하는지 확인할 수 있습니다, 자격 증명이 잘못된 경우 메시지 상자가 표시됩니다. 그러나 내 자격 증명이 정확하다면, 양식 중 아무 것도 내가 access_level에 넣은 것에 관계없이로드됩니다. 그것의 천천히 점점, 나는 여전히 매우 새로운 것으로 보이는 디버거를 사용하여 자습서를 통해 갈 메신저.

개인 무효 LoginBT_Click (개체 보낸 사람, EventArgs입니다 전자) {

 if (tryLogin(uname.Text, pword.Text) == true) 
     { 
      using (MySqlConnection con = new MySqlConnection("host="";user="";password=""; database="";")) 
      using (MySqlCommand cmd2 = new MySqlCommand("SELECT access_level FROM Staff WHERE username = '" + uname + "';")) 
      { 

       cmd2.Connection = con; 
       con.Open(); 


       object access_level = cmd2.ExecuteScalar(); 

       if (access_level != null && access_level != DBNull.Value) 
       { 
        if (access_level.ToString() == "1") 
        { 
         this.Dispose(); 
         CarerHomePage CarerHomePage = new CarerHomePage(); 
         CarerHomePage.Show(); 
        } 


        else if (access_level.ToString() == "2") 
        { 
         this.Dispose(); 
         AdministratorHome AdministratorHome = new AdministratorHome(); 
         AdministratorHome.Show(); 
        } 




       } 

      } 



     } 
     else 
     { 
      MessageBox.Show("Invalid Login Credentials"); 
     } 
} 

} 

} 내 눈 아

+0

+ uname.text + 이유였습니다. –