SQL run time error in asp.net c# - c#

I keep getting run time SQL query errors in asp.net. I am using c#. The error always starts with Incorrect Syntax near '(some word)'. I have checked and rechecked my code for any syntactic errors but never found any.. In the code below the error is Incorrect Syntax near 'user'. Please help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
public partial class LogIn : System.Web.UI.Page
{
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
protected void Page_Load(object sender, EventArgs e)
{
con.ConnectionString = #"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users \Sony\Documents\Library\App_Data\Library.mdf;Integrated Security=True;User Instance=True";
cmd.Connection=con;
con.Open();
}
protected void txt_user_TextChanged(object sender, EventArgs e)
{
}
protected void txt_pass_TextChanged(object sender, EventArgs e)
{
}
protected void btn_log_Click(object sender, EventArgs e)
{
cmd.CommandText="select count(*) from user where Username='"+txt_user.Text+"' and Password='"+txt_pass.Text+"'";
int count =Convert.ToInt16(cmd.ExecuteScalar());
if (count==1)
{
Response.Redirect("Home.aspx");
}
else
{
Label1.Text="Invalid Username or Password. Please try again..";
}
}

The reason of your error is the word user. It is a reserved keyword for SqlServer.
You need to encapsulate it with square brakets
select count(*) from [user] ....
Said that, now let's address the biggest problem of your code. Sql Injection
cmd.CommandText="select count(*) from [user] where Username=#uname " +
"and Password=#upass";
cmd.Parameters.AddWithValue("#uname", txt_user.Text)
cmd.Parameters.AddWithValue("#upass", txt_pass.Text);
int count =Convert.ToInt16(cmd.ExecuteScalar());
......
Using a parametrized query like this, protects your application from malicious input (see the referenced question) that could compromise (or destroy) the information stored in your database. Also you avoid problems with inputs that contains problematic characters like strings with single quotes or numeric decimal separators or date formatting difficulties.
There is another problem as I can see from your code above. Do not store the connection in global variables. There is no performance hit if you open the connection when needed and close afterwards.
It is called Connection Pooling and you don't keep a valuable resource locked when you don't use it.
So to sum it all:
protected void btn_log_Click(object sender, EventArgs e)
{
using(SqlConnection con = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=" +
#"C:\Users\Sony\Documents\Library\App_Data\Library.mdf;" +
#"Integrated Security=True;User Instance=True")
{
con.Open();
using(SqlCommand cmd = new SqlCommand("select count(*) from [user] where "+
"Username=#uname and Password=#upass", con)
{
cmd.Parameters.AddWithValue("#uname", txt_user.Text)
cmd.Parameters.AddWithValue("#upass", txt_pass.Text);
int count =Convert.ToInt16(cmd.ExecuteScalar());
......
}
}
}

The thing is, that "user" is a reserved word in SQL. Apart form the injection problem, your query should read:
select ... from [user] where

'User' is a reserved keyword in SQL server. If you have a table name 'user', you should put it in brakets within queries
select count(*) from [user] where ...

I agree fully with all that has been said by Steve, Roman and Alex.
If I should add something it is that you should try to minimize the usage of ad-hoc queries, that has been used in this example. Rather you should prefer to put the most part of the sql code in sql functions and stored procedures, since that can give a hugh improvement of the performance since those queries can be compiled the first time they are executed and the times executed afterward the database can focus on just to retreive data. With ad-hoc queries the query has to be compiled every time, which can actually take some time for more complex queries.
You can then execute the Stored Procedure like this:
using(SqlCommand cmd = new SqlCommand("dbo.IsValidLogin", con)
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#username", txt_user.Text)
cmd.Parameters.AddWithValue("#password", txt_pass.Text);
var isValidLogin =Convert.ToBool(cmd.ExecuteScalar());
...
}
If you have a Procedure declared in the database like this:
CREATE PROC dbo.IsValidLogin
#username nvarchar(50),
#password nvarchar(50)
AS
BEGIN
SELECT count(1)
FROM [user]
WHERE Username=#username
AND Password=#password
END;
See a Sql Fiddle exemple here.

Related

inserting data into SQL DB from C# ASP.NET

I am trying to insert values into my SQL database, the query works on the SQL side but when it comes to implement it from C# ASP.NET, it will not insert anything into the SQL database. The code is as follows:
public partial class About : Page
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
protected void Page_Load(object sender, EventArgs e)
{
con.Open();
}
protected void Button1_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand("insert into sanctuary(SName) values('test')", con);
cmd = new SqlCommand("insert into species(Name) values('test1')", con);
cmd = new SqlCommand("insert into breed(SpeciesID, BreedName, FoodCost, HousingCost) SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species", con);
cmd.ExecuteNonQuery();
con.Close();
}
}
}
Your help will be much appreciated!
If you want to execute three commands together you merge the sql of the three commands in a single string separating them with a semicolon (See Batch of Sql Commands)
string cmdText = #"insert into sanctuary(SName) values('test');
insert into species(Name) values('test1');
insert into breed(SpeciesID, BreedName, FoodCost, HousingCost)
SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species";
SqlCommand cmd = new SqlCommand(cmdText, con);
cmd.ExecuteNonQuery();
The first problem in your code is that you need to execute each single command and not just the last one. Finally, if you don't see even the insert for the last command could be because your table species is empty and thus the final command has nothing to insert.
Last note, the point underlined by Zohar Peled about NOT keeping a global connection object around, is very important, follow the advice.
You only execute the last command, so there is nothing in species. Since there is nothing in species, the select returns no results so nothing gets inserted into breed.
Also, keeping an SqlConnection object on the page level is not a good idea. SQL connections should be opened right before executing queries and disposed immediately after.
A better code would look like this:
using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using(var com = new SqlCommand("insert into sanctuary(SName) values('test');insert into species(Name) values('test1');insert into breed(SpeciesID, BreedName, FoodCost, HousingCost) SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species", con)
{
con.Open();
com.ExecuteNonQuery();
}
}
You can, of course, execute each SQL statement separately (though in this case it's not the best course of action since it means 3 round trips to the database instead of just one):
using(var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
using(var com = new SqlCommand("insert into sanctuary(SName) values('test');", con)
{
con.Open();
com.ExecuteNonQuery();
com.CommandText = "insert into species(Name) values('test1');";
com.ExecuteNonQuery();
com.CommandText = "insert into breed(SpeciesID, BreedName, FoodCost, HousingCost) SELECT SpeciesID, ('breed'), ('12'), ('21') FROM species;";
com.ExecuteNonQuery();
}
}

ExecuteNonQuery() doesn't work

Every time I try to run my code, I get this exception:
An unhandled exception of type 'System.Data.SqlClient.SqlException'
occurred in System.Data.dll
Additional information: Incorrect syntax near ')'.
Tried multiple workarounds, but I never get past the ExectueNonQuery line. Can someone tell me what's wrong with it?
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;");
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"',)", con);
cmd.ExecuteNonQuery();
con.Close();
}
While the other questions state the root problem, your trailing comma, you really must do better about your queries. Do not glue your query together like that, use parameters instead. If you do not you are opening yourself to huge security problems. Also you really must put the connection in a using statement so when a error does happen the connection will still be closed.
private void button1_Click(object sender, EventArgs e)
{
using(SqlConnection con = new SqlConnection(#"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;"))
{
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES (#idFis,#numeFis,#idFoldFis)",con);
cmd.Parameters.Add("#idFis", SqlDbType.NVarChar, -1).Value = idFis.Text;
cmd.Parameters.Add("#numeFis", SqlDbType.NVarChar, -1).Value = numeFis.Text;
cmd.Parameters.Add("#idFoldFis", SqlDbType.NVarChar, -1).Value = idFoldFis.Text;
cmd.ExecuteNonQuery();
}
}
The comma is your problem, but I would recommend a few other changes at least before moving on:
Don't embed your connection strings into each db connection request. Use app.config/web.config or anything else :)
Ensure your connections are commands are properly disposed of
Parameterize any SQL queries to prevent injection attacks
Abstract database commands into separate business layer
1. Utilize an "app.config" for connection strings
There are many docs out there on keeping a connection string secure, but at a minimum, don't embed straight into each of your connection code.
Add an "app.config" to your client project (or utilize the web.config of web projects). At a minimum, this looks like this:
<configuration>
<appSettings>
<add key="db" value="Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;" />
</appSettings>
</configuration>
Then add a reference to "System.Configuration" to your project, and you can reference it like this in your code:
var con = new SqlConnection(ConfigurationManager.AppSettings["db"]);
2. Ensure your connections ard commands are properly disposed
Wrap connections and commands in using. Here is an example:
using (var con = new SqlConnection(ConfigurationManager.AppSettings["db"]))
{
con.Open();
var sql = "/* My command here */";
using (var cmd = new SqlCommand(sql, con))
{
// SQL execution here
}
} // Closing is now handled for you (even if errors occur)
3. Parameterize any SQL queries to prevent injection attacks
Concatenating strings are very dangerous for SQL commands (just google "SQL Injection"). This is how to protect yourself.
using (var con = new SqlConnection(ConfigurationManager.AppSettings["db"]))
{
con.Open();
var sql = "INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES (#idFisier, #nume, #idFolder)";
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.Add("#idFisier", SqlDbType.VarChar).Value = idFis.Text;
cmd.Parameters.Add("#nume", SqlDbType.VarChar).Value = numeFis.Text;
cmd.Parameters.Add("#idFolder", SqlDbType.VarChar).Value = idFoldFis.Text;
cmd.ExecuteNonQuery();
}
} // Closing is now handled for you (even if errors occur)
4. Abstract database commands into separate business layer
It is usually best practice and will save you many headaches by writing separate classes (even class library) as your business layer that only contain your data commands. Then your UI would only handle calling the business layer methods.
If your database ever changes or you need to do similar functionality in other parts of your UI, it won't be very fun updating the same query all over your UI as opposed to just updating a single spot in your business layer.
Make SQL being readable and parametrized and you'll find the routine easy to implement:
// Extract a method (or even a class): do not mix UI and business logic/storage
// Just RDBMS logic: no UI controls or something at all
private static void CoreInsertFisier(string idFisier, nume, idFolder) {
// Do not hardcode the connection string, but read it (from settings)
// wrap IDisposable into using
using (SqlConnection con = new SqlConnection(ConnectionStringHere)) {
con.Open();
// Make sql readable (use verbatim strings #"...")
// Make sql parameterized
string sql =
#"INSERT INTO Fisier (
idFisier,
Nume,
idFolder)
VALUES (
#prm_idFisier,
#prm_Nume,
#prm_idFolder)";
// wrap IDisposable into using
using (SqlCommand cmd = new SqlCommand(sql, con)) {
// Parameters.Add(...) is a better choice, but you have to know fields' types
cmd.Parameters.AddWithValue("#prm_idFisier", idFisier);
cmd.Parameters.AddWithValue("#prm_Nume", nume);
cmd.Parameters.AddWithValue("#prm_idFolder", idFolder);
cmd.ExecuteNonQuery();
}
}
}
...
private void button1_Click(object sender, EventArgs e) {
// UI: just one call - please insert these three textbox into db
CoreInsertFisier(idFis.Text, numeFis.Text, idFoldFis.Text);
}
You have an extra trailing comma:
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;");
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"')",con);
cmd.ExecuteNonQuery();
con.Close();
}
Anyway as others said, it is a very bad idea to concatenate your query that way, since it could lead you to have sql injection on your code.
Try removing the , before the closing )
SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"')",con);

Incorrect syntax ASP.NET

I’m very new to ASP.net and have been following a few video tutorials to build a log in page. I successfully created my registration page fine that enters details into my table within the database fine however I can't get my log in page to work =/.I’ve been at this for a few hours and am not sure if any of you can help but it's worth a shot. The IDE I am using is visual studio (latest version).
I am getting the following error (clicking the image will give a closer view, but you probably already know that):
the error changes depending on who I try to log on as for example the above error was returned when trying to log in as john, the below error was returned trying to log in as admin.
shown below is my code used behind the log in button:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button2_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from [Table] where [Login]'" + Loginbox.Text + "'";
SqlCommand com = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string CheckPasswordQuery = "select Password from [Table] where [Login]='" + Loginbox.Text + "'";
SqlCommand Passcom = new SqlCommand(CheckPasswordQuery, conn);
string password = Passcom.ExecuteScalar().ToString().Replace(" ","");
if (password == Passwordbox.Text)
{
Session["New"] = Passwordbox.Text;
Response.Write("Password is correct");
}
else
{
Response.Write("Wrong password");
}
}
else {
Response.Write("User name does not exist");
}
}
}
Shown below is the form page view, which runs perfectly fine, the error gets returned when the log in button is pressed.
Shown below is the table definition:
And shown below is the data contained within the table:
Thank you all for your time and I appreciate any input any of you have to help solve this.
You have invalid syntax in your query. Please note that while many tutorials may show you to query like this, it's very insecure. You should use parameters. However, for the sake of this answer, you forgot the equal sign:
string checkuser = "select count(*) from [Table] where [Login] = '" + Loginbox.Text + "'";
Your syntax is incorrect, but it is actually safer if you parameterize it to avoid sql injection
string checkuser = "select count(*) from [Table] where [Login] = #user";
SqlCommand com = new SqlCommand(checkuser, conn);
com.Parameters.Add("#user", Loginbox.Text);
...

How to display data in gridview from MS Access?

I want to display information of user stored in a MS Access database. The user enters his userid and on clicking a button following function is called. But no data is being displayed. What am I doing wrong ?
System.Data.OleDb.OleDbConnection con;
System.Data.OleDb.OleDbDataAdapter da;
protected void Button1_Click(object sender, EventArgs e)
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
string sql = "SELECT * From Leave where userid="+Textbox1.Text;
da = new System.Data.OleDb.OleDbDataAdapter(sql, con);
DataTable t = new DataTable();
da.Fill(t);
GridView1.DataSource = t;
con.Close();
}
You need to call GridView1.DataBind()
GridView1.DataSource = t;
GridView1.DataBind();
Just a side-note, it is good practice to wrap your connection with using
using(con = new System.Data.OleDb.OleDbConnection())
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
...
...
}
This ensures your connection is properly disposed after use
You should use bind function:
protected void Button1_Click(object sender, EventArgs e)
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
string sql = "SELECT * From Leave where userid="+Textbox1.Text;
da = new System.Data.OleDb.OleDbDataAdapter(sql, con);
DataTable t = new DataTable();
da.Fill(t);
GridView1.DataSource = t;
GridView1.DataBind();
con.Close();
}
First off, please, please please don't concatenate your WHERE parameters in your SQL. Use Parameters. Second, Add a "using System.Data.OleDb" statement at the top of your module, so that you are not having to type things like:
System.Data.OleDb.OleDbDataAdapter
Over and over again.
Try the following code. Personally, when I have to work with data tables and such, I prefer to avoid all the DataAdapter nonsense, and keep it as simple as possible.
Note in the code below:
the "using" blocks. These place the variables created within them inside their own scope, and take care of disposal and such for you.
I used an OleDb Parameter instead of concatenating criteria. This is a much safer way to do things, and creates much cleaner and more readable code as well, especially in cases where you have several criteria in your WHERE clause.
I assume your UserID input is a string, since you are grabbing the value from a Textbox. If it is in fact an int value (such as an auto-incrementing id in MS Access) you will need to use an int data type instead. You may have to mess with it a little. When you are still figuring this stuff out, it can be a bit painful. However, using parameters increases security and maintainability.
Once you have obtained a data table as the return from the MyUsers method, you should be able to simply set the data source of your Gridview. If you have difficulties still, do as Steve suggests and check the Autogenerate columns property in the designer, or set it in code.
Not that I have moved the connection string to the project Properties/Settings. You should find this in the solution designer. Place your connection string there, in one spot, and you can obtain it from anywhere in your code. If you later change the connection string (such as moving your Db to another computer, server share, etc) you need only change it in one place.
SAMPLE CODE:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb; // put this here, and stop writing long namespaces inline
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Where possible, move code out of specific event handlers
// into methods which can be re-used from other client code.
// Here, I pulled the actual data access out into separate methods,
// and simply call it from the event handler:
this.LoadGridView(textBox1.Text);
}
private void LoadGridView(string UserID)
{
// Now we can load the gridview from other places in our
// code if needed:
this.dataGridView1.DataSource = this.MyUsers(UserID);
}
private DataTable MyUsers(string UserID)
{
var dt = new DataTable();
// Use a SQL Paramenter instead of concatenating criteria:
string SQL = "SELECT * FROM Leave WHERE userid = #UserID";
// The "using" statement limits the scope of the connection and command variables, and handles disposal
// of resources. Also note, the connection string is obtained from the project properties file:
using(OleDbConnection cn = new OleDbConnection(Properties.Settings.Default.MyConnectionString))
{
using (var cmd = new OleDbCommand(SQL, cn))
{
// For simpler things, you can use the "AddWithValue" method to initialize a new parameter,
// add it to the Parameters collection of the OleDBCommand object, and set the value:
cmd.Parameters.AddWithValue("#UserID", UserID);
// Get in, get out, get done:
cn.Open();
dt.Load(cmd.ExecuteReader());
cn.Close();
}
}
return dt;
}
}
}
Hope that helps. It's not how everyone might do it, but I have found it provides maximum flexibility, when you must work with MS Access.

Asp.net login script

i'm new to asp.net, i'm writing a login & registration script for learning database application. But the script seems not work. it stills can add duplicated username. Here is the script
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
public partial class Registration : System.Web.UI.Page
{
static string temp;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["earchConnectionString"].ConnectionString);
con.Open();
string cmdStr = "Select count(*) from [user] where UserName='" + TextBoxUN.Text + "'";
SqlCommand userExist = new SqlCommand(cmdStr, con);
int temp = Convert.ToInt32(userExist.ExecuteScalar().ToString());
con.Close();
if (temp == 1)
{
Response.Write("User Name Already Exist....<br /> Please Choose Another User Name.");
}
}
}
protected void Submit_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["earchConnectionString"].ConnectionString);
con.Open();
string insCmd = "Insert into [user] (UserName, Password, EmailAddress, FullName, level) values (#UserName,#Password,#EmailAddress, #FullName, #level)";
SqlCommand insertUser = new SqlCommand(insCmd, con);
insertUser.Parameters.AddWithValue("#UserName", TextBoxUN.Text);
insertUser.Parameters.AddWithValue("#Password", TextBoxPass.Text);
insertUser.Parameters.AddWithValue("#EmailAddress", TextBoxEA.Text);
insertUser.Parameters.AddWithValue("#FullName", TextBoxFN.Text);
insertUser.Parameters.AddWithValue("#level", level.SelectedValue.ToString());
try
{
insertUser.ExecuteNonQuery();
con.Close();
//Response.Redirect("Login.aspx");
Label1.Text = temp;
}
catch (Exception er)
{
Response.Write("Something wrong");
}
finally
{
//Any Special Action You Want To Add
}
}
}
Any can detect the problems?
thanks
You should do the check whether the username exists inside your Button_Click, not inside Page_Load. Ideally both queries should be executed within the same SQL transaction. Also you should absolutely use parametrized query for the first one (the same way you are doing in the second query) in order to prevent SQL injection.
Set primary key on the column UserName of the table user. So you don't have to check for the user existence in the database at the time of insertion, reducing an extra call to database. This way command.ExecuteNonQuery() won't allow you to insert duplicate users and throw exception and you can take necessary actions in the catch block of your code.
Make an unique field for your user login in SQL Database.
On account creation page on account creation button click event do it as following:
try
{
SqlCommand command = new SqlCommand("INSERT INTO Users(login,password) VALUES ('" + txtLogin.Text + "','" + txtPass.Text+ "');", con);
command.ExecuteNonQuery();
Response.Redirect("login.aspx");
}
catch (SqlException)
{
lblWrongLogin.Text = "Username already exists.";
}
Basically, when you try to write a duplicate login in SQL Database you get SQL exception, so you just catch it in your application and do whatever action you need (in most cases reload registration page).
P.S.:
consider using some hashing algorithm like MD5 to hash passwords before putting them in database. Also dont forget to hash passwords client-side when logging in.
P.P.S.: use SQL parameters for login, password and every other user-entered information to prevent SQL injection.

Categories