I have a problem in my vb.net code, I have a login form that is connected to a mysql database. It can already check if the user is in the database, now the next thing to do is to get the name, access level and userId from the database according to the logged in account, I have store it in a module that holds a global variable.
This is my code.
Module pubvars
Public Gplev As String
Public Gname As String
Public GuserId As Integer
End Module
Then I will use this variables on other forms, in the first session of logging in the variables was read correctly,but when I logged out, then login with a new user account, the variable passed was not updated, which is supposedly changed as a new account was logged in.
Here is the code where I declare the variables.
Dim search1 As MySqlCommand = New MySqlCommand("SELECT * FROM `login` WHERE login.username = '" & TextBox1.Text & "' AND login.password = '" & TextBox2.Text & "'", con)
con.Open()
Dim dr As MySqlDataReader = search1.ExecuteReader
Dim userFound As Boolean = False
While dr.Read
userFound = True
pubvars.Gname = dr("name").ToString
pubvars.Gplev = dr("permission_level").ToString
pubvars.GuserId = dr("userId").ToString
End While
If userFound = True Then
main_menu.Show()
Me.Hide()
Else
MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "Invalid Login")
TextBox1.Text = ""
TextBox2.Text = ""
End If
And here is the code where I used the variables in the second form.
Private Sub main_menu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Label3.Text = pubvars.Gname
If pubvars.Gplev = "2" Then
Button8.Enabled = False
Button8.Visible = False
ElseIf pubvars.Gplev = "3" Then
Button8.Enabled = False
Button8.Visible = False
ElseIf pubvars.Gplev = "4" Then
Button8.Enabled = False
Button8.Visible = False
End If
End Sub
For logout I have the following code.Is this right or it is not enough for logout?
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
pubvars.Gname = ""
pubvars.Gplev = "0"
login.Show()
Me.Hide()
End Sub
Move the login var assignment logic from Load event to Activated event. The Load event gets executed only once, when you load a Form for the first time.
The Activated event happens every time you display the form .Show(). If you move the code from Load event to Activated, you should fix the issue.
Related
I'm working on a discord bot.
I'm currently working on the login panel (the classic MySQL login way, with the SELECT statement.).
But I've started doing a thing called 2FA, and the way that it works, is the following: If the login was successful the application should set the readytotwofactor column (in MySQL) to true. If it's true, the discord bot generates a 10 letter code, which is appearing in the twofactorcode column. The BOT knows who to send the message to by watching the username entered in the TextBox when logging in. It looks for this in MySQL, and each column (registered username) is associated with a discord ID. Based on this, the BOT knows to whom to send the code that is checked in the MySQL column, the application can identify whether the code is correct or not. Once the code has been sent, the readytotwofactor column will automatically change to false, and the code I wrote should change the value in the twofactorcode column to 0.
My problem, though, is that it doesn't work.
Here is the source code: (Form3 is the login form, and Form4 is the 2FA form.).
Imports MySql.Data.MySqlClient
Public Class Form3
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
Dim connection As New MySqlConnection("just the login stuff")
Dim command As New MySqlCommand("SELECT * FROM karolyguilogin WHERE username=#username AND pass=#password", connection)
command.Parameters.Add("#username", MySqlDbType.VarChar).Value = TextBox1.Text
command.Parameters.Add("#password", MySqlDbType.VarChar).Value = TextBox2.Text
Dim command1 As New MySqlCommand("UPDATE `karolyguilogin` readytotwofactor SET readytotwofactor=#readytotwofactor WHERE username=#username", connection)
Dim Adapter As New MySqlDataAdapter(command)
Dim table As New DataTable()
Adapter.Fill(table)
connection.Open()
If TextBox1.Text = "" Then
MessageBox.Show("írj be valamit!")
Me.Close()
End If
If TextBox2.Text = "" Then
MessageBox.Show("írj be valamit!")
Me.Close()
End If
If table.Rows.Count() <= 0 Then
MessageBox.Show("Helytelen felhasználónév, vagy jelszó!")
Else
command1.Parameters.Add("#readytotwofactor", MySqlDbType.VarChar).Value = "true"
MessageBox.Show("Hamarosan megkapod a 2FA kódod!")
Me.Hide()
Form4.Show()
Me.Close()
End If
connection.Close()
End Sub
End Class
Imports MySql.Data.MySqlClient
Public Class Form4
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connection As New MySqlConnection("just the login stuff")
Dim command As New MySqlCommand("SELECT twofactorcode FROM karolyguilogin WHERE twofactorcode = #twofactorcode <> NULL", connection)
command.Parameters.Add("#twofactorcode", MySqlDbType.VarChar).Value = TextBox1.Text
connection.Open()
If TextBox1.Text = "" Then
MessageBox.Show("írj be valamit!")
Me.Close()
End If
Dim Adapter As New MySqlDataAdapter(command)
Dim table As New DataTable()
Adapter.Fill(table)
If table.Rows.Count() <= 0 Then
MessageBox.Show("A kódod helytelen, próbálkozz újra!")
Else
Dim command1 As New MySqlCommand("UPDATE `karolyguilogin` twofactorcode SET twofactorcode=#twofactorcode WHERE twofactorcode <> NULL", connection)
MessageBox.Show("A kódod helyes! Beléphetsz a felületre!")
command1.Parameters.Add("#twofactorcode", MySqlDbType.VarChar).Value = "NULL"
Me.Hide()
Form3.Hide()
Form1.Show()
Me.Close()
Form3.Close()
End If
connection.Close()
End Sub
End Class
In the first place, passwords should never be stored as plain text. I am hoping you have omitted the encryption code for brevity.
In ADO.net connections and commands need to be disposed, not just closed. A Using block will handle this for you even if there is an error.
Don't pull down the entire record. You only need to know if it exists. You don't need a DataAdapter to do this.
Do your validation outside the Using block before any database objects are created. Also, how to you expect the user to "Enter something" when you close the Form?
Use the same command for the second query, just change the CommandText. Note that we already have the #username parameter and the #readytotwofactor parameter is not needed because it can be hardcoded in the sql string.
Why hide the Form and then close it 2 lines later?
Perhaps your code doesn't work because you never execute the second command.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Validate first before the database code
If TextBox1.Text = "" OrElse TextBox2.Text = "" Then
MessageBox.Show("írj be valamit!")
Exit Sub
End If
Dim ReturnCount As Integer
Using connection As New MySqlConnection("datasource=sql11.freemysqlhosting.net;port=3306;username=sql11396664;password=eG1IbxNzLR;database=sql11396664"),
command As New MySqlCommand("SELECT Count(*) FROM karolyguilogin WHERE username=#username AND pass=#password", connection)
command.Parameters.Add("#username", MySqlDbType.VarChar).Value = TextBox1.Text
command.Parameters.Add("#password", MySqlDbType.VarChar).Value = TextBox2.Text
connection.Open()
ReturnCount = CInt(command.ExecuteScalar())
If ReturnCount = 0 Then
MessageBox.Show("Helytelen felhasználónév, vagy jelszó!")
Else
command.CommandText = "UPDATE `karolyguilogin` readytotwofactor SET readytotwofactor='true' WHERE username=#username"
command.ExecuteNonQuery()
MessageBox.Show("Hamarosan megkapod a 2FA kódod!")
Form4.Show()
Me.Close()
End If
End Using 'Closes and disposes both the command and the connection
End Sub
I assume there is some sort of trigger in the database when readytotwofactor is set to true.
You realize your Update will set all records in the karolyguilogin table to the string "NULL" not just the the user attempting to log in. If this is a multiuser database this could cause a problem.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If TextBox1.Text = "" Then
MessageBox.Show("írj be valamit!")
Exit Sub
End If
Dim ReturnCount As Integer
Using connection As New MySqlConnection("datasource=sql11.freemysqlhosting.net;port=3306;username=sql11396664;password=eG1IbxNzLR;database=sql11396664"),
command As New MySqlCommand("SELECT Count(*) FROM karolyguilogin WHERE twofactorcode = #twofactorcode", connection)
command.Parameters.Add("#twofactorcode", MySqlDbType.VarChar).Value = TextBox1.Text
connection.Open()
ReturnCount = CInt(command.ExecuteScalar())
If ReturnCount = 0 Then
MessageBox.Show("A kódod helytelen, próbálkozz újra!")
Else
command.CommandText = "UPDATE `karolyguilogin` SET twofactorcode='NULL' WHERE twofactorcode <> 'NULL';"
MessageBox.Show("A kódod helyes! Beléphetsz a felületre!")
Form1.Show()
Me.Close()
End If
End Using 'Closes and disposes both the command and the connection
End Sub
I had fun translating the Hungarian message boxes so I could better understand your code.
I have a very simple application where a user will login and be redirected to the dashboard. I got the login part working, however, my next goal is to be able to store the users information for later use on other forms.
Example: User "admin" logs in successfully. I need to be able to store every column in the table for admin so that we can call the user's information for welcome messages, user information form, etc without having to query the database everytime.
I believe this can be accomplished with a class, however, I'm unsure how to rewrite my login script to save all details into a class.
I've tried creating a class, and adding Public Shared properties for each column but I'm not sure how to get every column into the class rather than just the username.
Imports MySql.Data.MySqlClient
Public Class frmLogin
'count is number of invalid login attempts
Dim count As Integer
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
count = count + 1
Dim x As New MySqlConnection
Dim admin As New MySqlCommand
Dim dr1 As MySqlDataReader
ConnectDatabase()
admin.Connection = conn
admin.CommandText = "SELECT user.username, user.password FROM user WHERE user.username = '" & txtUsername.Text & "' and user.password = '" & txtPassword.Text & "'"
dr1 = admin.ExecuteReader
If dr1.HasRows Then
'Read the data
dr1.Read()
Me.Hide()
frmDashboard.Show()
Else
MsgBox("Invalid Username or Password! " & vbCrLf & count & " out of 3 attempts remaining.")
If count >= 3 Then
MsgBox("You have exceeded the maximum number of attempts to login. Account has been disabled. Please contact OJFS helpdesk at extension 100.", MsgBoxStyle.Critical)
txtUsername.Enabled = False
txtPassword.Enabled = False
End If
End If
Connect.conn.Close()
End Sub
Dim Assistance As Boolean = False
Private Sub linkLoginHelp_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles linkLoginHelp.LinkClicked
If Assistance = True Then
Me.Height = 284
Me.CenterToScreen()
Assistance = False
txtUsername.Select()
Else
Me.Height = 463
Me.CenterToScreen()
Assistance = True
txtUsername.Select()
End If
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Application.Exit()
End Sub
End Class
The Using...End Using blocks ensure that your database objects are closed and disposed even if there is an error.
Of course in a real application you would NEVER store passwords as plain text.
Comments in line.
'Your class might look something like this
Public Class User
Public Shared ID As Integer
Public Shared Name As String
Public Shared Department As String
Public Shared Address As String
End Class
Private count As Integer
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
count = count + 1
'keep connections local for better control
'pass the connection strings directly to the constructor of the connection
Using cn As New MySqlConnection("Your connection string")
'pass the query and the connection directly to the constructor of the commmand
Using cmd As New MySqlCommand("SELECT * FROM user WHERE user.username = #User and user.password = #Password;", cn)
'Always use parameters to avoid SQL injection
cmd.Parameters.Add("#User", MySqlDbType.VarChar).Value = txtUsername.Text
cmd.Parameters.Add("#Password", MySqlDbType.VarChar).Value = txtPassword.Text
'Open the Connection at the last possible minute.
cn.Open()
Using dr1 = cmd.ExecuteReader
If dr1.HasRows Then
dr1.Read()
'The indexes of the data reader depent on th order of the fields in the database
User.ID = CInt(dr1(0))
User.Name = dr1(1).ToString
User.Department = dr1(2).ToString
User.Address = dr1(3).ToString
Me.Hide()
frmDashboard.Show()
Return 'a successful login will end here
End If
End Using 'closes and disposed the reader
End Using 'close and disposes the command
End Using 'closes and dipose the connection
MsgBox("Invalid Username or Password! " & vbCrLf & count & " out of 3 attempts remaining.")
If count >= 3 Then
MsgBox("You have exceeded the maximum number of attempts to login. Account has been disabled. Please contact OJFS helpdesk at extension 100.", MsgBoxStyle.Critical)
btnLogin.Enabled = False 'Instead of the text boxes disable the button.
'If you just disable the text boxes they can keep clicking the button and opening connections.
End If
End Sub
I am working on a school voting system. I Have tried this several times and there is no error but my login button doesn't work if I enter details and click login.
I use Visual Studio 2013 and would be glad if anyone can be of assistance.
Thank you
Imports MySql.Data.MySqlClient
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ConnectToSQL()
End Sub
'connecting to sql method
Private Sub ConnectToSQL()
Dim con As New MySqlConnection
Dim cmd As New MySqlCommand
Dim StudentId As String
Dim StudentPassword As String
Try
If con.ConnectionString = "Data source= localhost; port=3306; database= Students; user=root; password=;" Then
con.Open()
cmd.Connection = con
cmd.CommandText = "SELECT StudentId, StudentPassword, StudentName FROM members"
Dim lrd As MySqlDataReader = cmd.ExecuteReader()
If lrd.HasRows Then
While lrd.Read()
StudentId = lrd("StudentId").ToString
StudentPassword = lrd("StudentPassword").ToString
If StudentPassword = TextBox1.Text And StudentId = TextBox1.Text Then
MsgBox("you logged in succesfully")
Me.Hide()
Form2.Show()
TextBox1.Text = ""
TextBox2.Text = ""
End If
End While
Else
MsgBox("Username and password do not match")
TextBox2.Text = ""
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox1.Text = ""
TextBox2.Text = ""
TextBox1.Focus()
End Sub
End Class
From what I can see your problem is your first if statement:
If con.ConnectionString = "Data source= localhost; port=3306; database= Students; user=root; password=;" Then
This checks if the connectionstring is set to this value and will most definitely evaluate to false.
I assume that you want to set these settings and then open the connection to the database and not check if these settings are the set to a specific string
To make it work just remove this if statement and just set the connectionstring like this and then open the connection
con.ConnectionString = "Data source= localhost; port=3306; database= Students; user=root; password=;" Then
First, I'm going to assume you have a typo here, as it's using the username and password as the same textbox:
If StudentPassword = TextBox1.Text And StudentId = TextBox1.Text Then
Password is probably the 2nd one, forming this:
If StudentPassword = TextBox2.Text And StudentId = TextBox1.Text Then
Since you are a student and new to this, not going to get into the parameters discussion, or SQL parameters or filtering, hashing passwords or anything like that, but a couple changes:
Your else on the not hasrows:
MsgBox("Username and password do not match")
TextBox2.Text = ""
The problem with this is that in your case, having no rows just means there's no members in the database, not really information you need, or should tell someone.
Also, you don't need to blank out the username and password if you are going to hide the form anyway. The studentFound var below is used to identify if a match was found. We want to display an error if no match was found.
So, that gives us this:
While lrd.Read()
StudentId = lrd("StudentId").ToString
StudentPassword = lrd("StudentPassword").ToString
If StudentPassword = TextBox2.Text And StudentId = TextBox1.Text Then
MsgBox("you logged in succesfully")
Me.Hide()
Form2.Show()
studentFound = True
End If
End While
If Not studentFound Then
MsgBox("Username/Password Combination Not Found")
TextBox1.Text = ""
TextBox2.Text = ""
End If
I currently have a login page login.aspx that copies "affID" into a session and uses it on another page dashboard.aspx
login.aspx file looks like this :
Dim Query As String
Query = "select * from mdxmain.taffiliate where affID = '" & username.Text & "' and affPassword = '" & password.Text & "'"
COMMAND = New MySqlCommand(Query, MysqlConn)
Session("affID") = username.Text
READER = COMMAND.ExecuteReader
Dim count As Integer
count = 0
While READER.Read
count = count + 1
End While
If count = 1 Then
Response.Redirect("dashboard.aspx")
Else
Literal1.Text = "Invalid credentials"
End If
MysqlConn.Close()
Finally
End Try
MysqlConn.Dispose()
dashboard.aspx session load file looks like this :
Dim userid As String = HttpContext.Current.Session("affID")
I need help with not allowing access to the dashboard.aspx file without having a valid session. Also how to timeout the session after 2minutes
In your dashboard page_load event, check if the session variable is nothing, if it is, then redirect to your login page.
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim userid As String = HttpContext.Current.Session("affID")
if ( userid is Nothing) then
Response.Redirect("login.aspx")
end if
End Sub
Update
For the timeout there is some good information here
**i have simple application, but i dont know how to fix it.
this pic when i try to edit my database--> http://i861.photobucket.com/albums/ab171/gopak/sa_zps5a950df5.jpg
when i click button edit i want my access data will be update.this is my code..
thanks for your advice**
Imports System.Data.OleDb
Public Class Form2
Public cnstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Gop's\Downloads\admin site\admin site\admin site\bin\Debug\data_ruangan.accdb"""
Public cn As New OleDbConnection
Public cmd As New OleDbCommand
Public adaptor As New OleDbDataAdapter
Private Sub logout_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles logout_btn.Click
Form1.Show()
Me.Close()
End Sub
Private Sub exit_btn_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles exit_btn.Click
Dim a As Integer
a = MsgBox("Are you sure want to exit application?", vbInformation + vbYesNo, "Admin Site Virtual Tour Application")
If a = vbYes Then
End
Else
Me.Show()
End If
End Sub
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'Data_ruanganDataSet.data_ruangan' table. You can move, or remove it, as needed.
Me.Data_ruanganTableAdapter.Fill(Me.Data_ruanganDataSet.data_ruangan)
End Sub
Private Sub DataGridView1_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick
Dim i = DataGridView1.CurrentRow.Index
Label7.Text = DataGridView1.Item(0, i).Value
txtName.Text = DataGridView1.Item(1, i).Value
txtLocation.Text = DataGridView1.Item(2, i).Value
txtCapacity.Text = (DataGridView1.Item(3, i).Value).ToString
txtOperational.Text = (DataGridView1.Item(4, i).Value).ToString
txtInformation.Text = DataGridView1.Item(5, i).Value
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'If txtName.Text <> "" And txtLocation.Text <> "" And txtCapacity.Text <> "" And txtOperational.Text <> "" And txtInformation.Text <> "" Then
Dim i = DataGridView1.CurrentRow.Index
Dim ID = DataGridView1.Item(0, i).Value
Dim cmd As New OleDb.OleDbCommand
If Not cn.State = ConnectionState.Open Then
cn.Open()
End If
cmd.Connection = cn
cmd.CommandText = ("update data_ruangan set Name = '" & txtName.Text & _
"',Location = '" & txtLocation.Text & "',Capacity = '" & txtCapacity.Text & _
"',Operational_Hours ='" & txtOperational.Text & "',Information = '" & txtInformation.Text & ";")
cmd.ExecuteNonQuery()
cn.Close()
txtName.Text = ""
txtLocation.Text = ""
txtCapacity.Text = ""
txtOperational.Text = ""
txtInformation.Text = ""
'End If
End Sub
Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
End Sub
End Class
Try to use a parameterized query to execute your code. The error message is relative to the fact that you haven't initialized your connection with the information contained in the ConnectionString.
Here an example on how to do that...... but......
Dim cmdText = "update data_ruangan set [Name] = ?,Location = ?,Capacity = ?, " & _
"Operational_Hours =?,Information = ?;"
Using cn = new OleDbConnection( cnstring )
Using cmd = OleDb.OleDbCommand(cmdText, cn)
cn.Open
cmd.Parameters.AddWithValue("#p1", txtName.Text)
cmd.Parameters.AddWithValue("#p2", txtLocation.Text)
cmd.Parameters.AddWithValue("#p3", txtCapacity.Text)
cmd.Parameters.AddWithValue("#p4", txtOperational.Text)
cmd.Parameters.AddWithValue("#p5", txtInformation.Text)
'''' WARNING ''''
' WITHOUT A WHERE STATEMENT YOUR QUERY WILL UPDATE
' THE WHOLE TABLE WITH THE SAME VALUES
'''' WARNING ''''
cmd.ExecuteNonQuery()
End Using
End Using
txtName.Text = ""
txtLocation.Text = ""
txtCapacity.Text = ""
txtOperational.Text = ""
txtInformation.Text = ""
This code updates all the records of your table with the same value, so, unless you have only one record and update Always the same record you need to add a WHERE condition to your command.
Also, the NAME word is a reserved keyword in Access 2007/2010 and it is better to encapsulate that word with square brackets to avoid a syntax error message.
I have also removed the global variable OleDbConnection and used a local one that will be closed and destroyed when the code exits from the Using statement. This is the correct way to handle disposable objects, in particular every connection object is Always to be used in this way to release as soon as possible the expensive unmanaged resource used by the object.