3个问题:1、下面是一个简单的登录,不知道是不是我网速的问题,每次登录等待的时间都比较长(验证用户名密码)。
想实现在登录的时候,弹出个等待的提示窗体,直到验证完成,请问怎么做简单点?2、下面这种连接数据库验证用户名密码的方法在效率和安全上是不是有问题?有没有更好的方法?3、这样连接数据库会不会暴露连接地址、用户名和密码?如果会,有没有什么方法可以更安全点? ^_^using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MySql.Data;
using MySql.Data.MySqlClient;namespace test_mysql
{
    public partial class login : Form
    {
        private string strTs = "出错";        public login()
        {
            InitializeComponent();
        } 
        private void login_Load(object sender, EventArgs e)
        {
   
        }        //通用显示信息的函数
        private void showMsg(string strNr)
        {
            MessageBox.Show(this, strNr, strTs, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }        //“退出”按钮的处理事件
        private void butout_Click(object sender, EventArgs e)
        {
            this.Close();
        }        private void butIn_Click(object sender, EventArgs e)
        {
            if (txtuser.Text.Trim() == "")
            {
                errlogin fm = new errlogin();
                fm.Show();
                 return;
            }
            if (txtpass.Text.Trim() == "")
            {
                errlogin fm = new errlogin();
                fm.Show();
                return;
            }
            try
            {                MySql.Data.MySqlClient.MySqlConnection cnn = new MySqlConnection("host=\;database=;uid=;pwd=");
                string strSql = "select * from tb_user where username='" + txtuser.Text.Trim() + "' and password='" + txtpass.Text.Trim() + "'";
                cnn.Open();
                MySqlCommand cmm = new MySqlCommand(strSql, cnn);
                MySqlDataAdapter da = new MySqlDataAdapter();
                da.SelectCommand = cmm;
                DataSet ds = new DataSet();
                da.Fill(ds);
                DataTableReader dr = ds.CreateDataReader();
                if (dr.Read())
                {
                    Form1 frm = new Form1();
                    frm.Show();
                    this.Hide();                }
                else
                {
                    errlogin fm = new errlogin();
                    fm.Show();
                    //showMsg("验证失败,请重新输入用户名和密码!");
                    txtuser.Focus();
                }
                cnn.Close();
            }
            catch (Exception ex)
            {
                showMsg("验证用户名和密码时发生错误,错误为:" + ex.Message);
            }
        }    }
}

解决方案 »

  1.   

    txtpass.Text 应该用 MD5 或 SHA 之类的方法加密后再存放在数据库中,验证时也同样加密后比较。
      

  2.   

     string strSql = "select * from tb_user where username='" + txtuser.Text.Trim() + "' and password='" + txtpass.Text.Trim() + "'"; 这样写容易被注入攻击的 换成sqlparam传参吧
      

  3.   

    string strSql = "select * from tb_user where username=@username  and password=@password";数据库存储的@password 是经过MD5加密的 
    用户登录后 就把 @password 进行MD5加密 然后 查询
    把@username  和加密后的@password 作为参数 加入 哈西表
    hastabletemp.add(@username,username);
    hastabletemp.add(@password ,MD5password );代码是 VB的 改一下就可以了
            Public Overloads Shared Function FetchData(ByVal QryID As String, ByVal Parameters As Hashtable) As DataTable
                Try
                    Dim strQuery As String = FetchQuery(QryID)                'Justin 31-Mar-05
                    If LCase(Left(strQuery, 3)) = "spr" Then 'Stored Procedure
                        Return ExecuteDataTable(strQuery, CommandType.StoredProcedure, Parameters)
                    Else
                        Return ExecuteDataTable(strQuery, CommandType.Text, Parameters)
                    End If            Catch eFetch As SqlHelperException
                    Throw eFetch
                End Try
            End Function        Private Overloads Shared Function ExecuteDataTable(ByVal SqlStr As String, ByVal cmdType As CommandType, _
                                                               ByVal SqlParameters As Hashtable) As DataTable            Dim sqlConn As New SqlConnection(getConnectionString)
                Dim sqlCmd As New SqlCommand(SqlStr)
                Dim sqlDA As New SqlDataAdapter
                Dim dtSql As New DataTable            Dim strDebug As String 'Debuging            strDebug = " DML Statement " & ControlChars.CrLf & SqlStr & ControlChars.CrLf
                Try
                    sqlConn.Open()                With sqlCmd
                        .Connection = sqlConn
                        .CommandType = cmdType
                    End With
                    If Not (SqlParameters Is Nothing) Then
                        Dim hsEnum As IDictionaryEnumerator = SqlParameters.GetEnumerator                    With sqlCmd
                            While hsEnum.MoveNext
                                .Parameters.Add(hsEnum.Key, hsEnum.Value)                            'For Debugging
                                If Not hsEnum.Value.GetType Is GetType(System.Byte()) Then
                                    strDebug += hsEnum.Key & "=" & hsEnum.Value & ","
                                End If
                            End While
                        End With                End If                sqlDA.SelectCommand = sqlCmd                sqlDA.Fill(dtSql)                Return dtSql            Catch ExDB As SqlException
                    sqlConn.Close()
                    strDebug += ControlChars.CrLf & ExDB.Message
                    Throw New SqlHelperException(strDebug, ExDB)            Catch Ex As Exception
                    sqlConn.Close()
                    strDebug += ControlChars.CrLf & Ex.Message
                    Throw New SqlHelperException(strDebug, Ex)                Throw Ex
                Finally
                    sqlConn.Close()
                End Try
            End Function 'ExecuteDataTable
      

  4.   

    应该是网速的原因,代码没看出来会影响效率。你不用弹出窗体,在登陆页放个进度条控件就ok
    不安全,用c#加密类进行密码加密,使用参数化防止注入攻击
      

  5.   

    楼上说的都有道理,不过LZ最好去下载源码看看吧,你这样写,实在是不是很合适,其中包括连接字符串的写法和sql的拼装,还有sql的写法,都存在问题
      

  6.   

    支持一下
    楼上的各位都已经都说得不错
    建议你把连接字符串写到web.config里面
    数据层相关语句封装成一个专门的类
    sql语句用sqlparam传参