VB.NET - Formulário de Login II
Eu já tratei do assunto da criação de um formulário de login no artigo : VB.NET - Criando um formulário de login. Estou voltando ao tema devido a solicitação de um usuário, e, basicamente irei mostrar como você pode criar um formulário de login com acesso a uma tabela onde estão armazenados os dados : UsuarioID e Senha , que representam respectivamente o nome do usuário e a senha.
A diferença fica por conta da geração do Hash da senha que ficará armazenado no banco de dados. Desta forma a informação fica protegida pois mesmo que alguém consiga ter acesso a tabela de senhas somente terá o hash da senha e não a senha usada.
Repetindo o que já foi dito no artigo - : Gerando Hash e comparando Arquivos.
"Toda vez que o usuário digitar a senha, o sistema deverá aplicar o algoritmo hash na mesma para obter o MD. Se um intruso conseguir acessar o banco de senhas, verá um monte de códigos que não farão sentido e o intruso não terá como aplicar algoritmos de reversão, pois este é um dos princípios do hash - a sua irreversibilidade. "
O projeto é composto de :
1-) Dois formulários :
formulário de login - frmLogin.vb - Este será o formulário que o projeto irá carregar solicitando o nome e a senha do usuário.
formulário principal - Principal.vb - Após efetuar o login com sucesso , o este formulário será exibido.
2-) Um módulo - Estou usando um módulo para mostrar que não precisamos obrigatoriamente criar um módulo de classe este fim.
Login.vb - que irá conter os seguintes membros :
- variáveis globais
g_login - armazena o nome do usuário
conString - armazena a string de conexão com o banco de dados
DBcon - armazena a conexão com o banco de dados
- A classe util - que possui o método estático (shared) GeraHash() , que irá gerar o hash para o texto da senha informada
Imports System.Security.CryptographyImports System.textModule Login'variáveis públicas Public g_login As String Public conString As String Public DBCon As System.Data.OleDb.OleDbConnection
'Retorna um byte array baseado no texto origem Dim ByteSourceText() As Byte = Ue.GetBytes(texto)'Instancia um objeto MD5 Dim Md5 As New MD5CryptoServiceProvider'Calcula o valor do hash para o texto origem Dim ByteHash() As Byte = Md5.ComputeHash(ByteSourceText)'Converte o valor obtido para o formato string Return Convert.ToBase64String(ByteHash)End Function End Class
|
3-) O banco de dados Acesso.mdb criado no MSAccess contendo a tabela Usuarios com a seguinte estrutura e dados:
![]() |
|
A estrutura da tabela Usuários | Incluindo um usuário e gerando um hash para senha |
O acesso ao banco de dados será feito via DataReader retornando o UsuarioID e Senha.
O código do evento Click associado ao botão Login do formulário frmLogin.vb é o seguinte :
' Variavel usada para controlar o número de tentativas de logon do usuário Dim iConta As Integer 'Variável que instancia um objeto do tipo formulário Principal previamente criado 'e que será carreagdo apos efetuar um logon com sucesso Dim frmMain As New Principal Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click 'A string e conexão é usada para para descrever o tipo de banco de dados 'a localização e os quesitos de segurança usados na conexao Dim ConString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Password="""";User ID=Admin;Data Source=d:\teste\Acesso.mdb" 'Cria um novo objeto conenction e atribui a string de conexão acima Dim DBCon As New OleDb.OleDbConnection(ConString) 'a variávael g_login é publica e esta definida no modulo Login.vb 'é usada para armazeanr o nome do usuário no login e repassar a informação entre os formulários. g_login = Me.txtUsuario.Text 'atribui a senha a variavel strSenha Dim strSenha As String = Me.txtSenha.Text 'se o usuário ou a senha estiverem vazios avisa o usuário If g_login = String.Empty Or strSenha = String.Empty Then MessageBox.Show("Informação Incompleta. Preencha os campos com o nome do usuário e senha.", "Informação Incompleta") Me.txtUsuario.Focus() Return End If 'O banco de dados possui dois campos na tabela Usuarios '-UsuarioID uma chave primária do tipo texto que armazena o nome do usuário '-Senha que é um texto que guarda a senha do usuário Dim strsql As String = "SELECT UsuarioID, Senha FROM Usuarios WHERE UsuarioID='" & g_login & "' " 'define um comando sobe a conexão para selecionar o usuario e a senha Dim cm As New OleDb.OleDbCommand(strsql, DBCon) 'cria um objeto datareader Dim dr As OleDb.OleDbDataReader 'define variaveis de controle Dim valido As Boolean = False Dim Flag As Boolean = False Try 'abre a conexao DBCon.Open() 'executa um comando e gera um datareader (dr) dr = cm.ExecuteReader 'se houver dados retornados If dr.HasRows Then 'percorre o datareader While dr.Read 'se o Hash da senha informada for igual ao hash armazenado no banco de dados define 'a variavel valido como True If util.GeraHash(strSenha) = dr.Item("Senha") Then valido = True End If End While 'define a variavel controle Flag como true Flag = True End If 'fecha o datareader dr.Close() 'incrementa o contador de tentativas iConta = iConta + 1 'se a senha é valida exibe o formulário principal If valido = True Then Me.Hide() frmMain.Show() 'se o numero de tentativas for maior que 3 então avisa ao usuário ElseIf iConta > 3 Then Me.Text = "Login - Tentativa " & iConta.ToString MessageBox.Show(" Você ultrapassou o número de tentativas. Contate o suporte !", "Número de tentativas ultrapassado.") Me.Close() 'se Flag for false então o usuário é inválido ElseIf Flag = False Then MessageBox.Show("Nome de usuário Inválido, tente novamente ! ", "Informação Inválida") Me.txtUsuario.Focus() Me.txtUsuario.Text = "" Me.txtSenha.Text = "" Me.Text = "Login - Tentativa " & iConta.ToString Else 'senha inválida MessageBox.Show("Senha Inválida, tente novamente ! ", "Informação Inválida") Me.txtSenha.Focus() Me.txtSenha.Text = "" Me.Text = "Login - Tentativa " & iConta.ToString End If 'trata as exceções Catch exOledb As OleDb.OleDbException MessageBox.Show(exOledb.Message, "Erro de acesso ao Banco de Dados", MessageBoxButtons.OK, MessageBoxIcon.Error) Catch ex As Exception MessageBox.Show(ex.Message, "Erro genérico", MessageBoxButtons.OK, MessageBoxIcon.Error) Finally 'se a conexão esta aberta fecha e libera os objetos If DBCon.State = ConnectionState.Open Then DBCon.Close() End If cm = Nothing dr = Nothing DBCon.Dispose() 'chama o coletor de lixo GC.Collect() End Try End Sub |
Destaques do código acima:
DataReader
As propriedades e métodos mais usadas dos objetos DataReader são :
Para criar um objeto DataReader usamos o método ExecuteReader de um objeto Command . Abaixo um exemplo simples de como fazer isto :
Dim leitor As SQLDataReader = cmd.ExecuteReader() |
- Para criar um DataReader (OleDbDataReader) usamos o método ExecuteReader do objeto OleDbCommand, o qual retorna um objeto do tipo OleDbDataReader, o qual baseado na Consulta(strsql) usada com o objeto OleDbCommand retorna os registros encontrados na tabela Usuarios. (Enquanto o OleDbDataReader estiver em uso é necessário ter um objeto do tipo OleDbConnection ativo, i.e, uma conexão com a a base de dados.)
- A versão 1.1 do .NET Framework trouxe uma nova propriedade chamada HasRows para a classe DataReader, que retorna um valor Booleano indicando se há ou não linhas no DataReader. Se existir é informado True, caso contrário, False.
Este é um exemplo básico e deve ser melhorado. Que tal implementar a chamada ao frmlogin em uma rotina Sub Main() e isolar a camada de acesso aos dados ?
Pegue o código do projeto aqui :
formLogin.zip
Até o próximo artigo VB.NET...
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
-
ADO.NET - Uma visão geral I : Objetos Connnection , Command e DataReader
-
VB.NET
- Preenchendo um DataTable a partir de um DataReader.
-
VB.NET
- Criando um DataReader para uma conexão genérica.
-
ADO.NET - Convertendo um DataReader para um DataSet