Not without SSL
This is not secure if the password is sent over the network in plain text. Hashing the password on the server side is also not secure if the password is sent over the network in plain text.
Since the HTML <input type="password"/>
tag sends its contents in plain text, this will be a problem no matter how you store the password on the server, unless your website uses SSL to transmit the password.
(HTTP authentication, which pops up a dialog box in the browser asking for a password, may or may not be clear text, depending on what authentication mechanisms the server and browser have in common. So that could be a way to avoid this without using SSL.)
Not if the site administrators are suspect
Now, supposing you're using HTTPS to do the web site, this could be secure if you trust your site administrators (who can read plain text passwords), and other people who have access to the machine to behave properly. Now, it may be obvious that they can do anything they want with your website (since they administer it), but if they can read the password, the may also be able to use the stolen login/password pairs on other people's sites.
A way that keeps passwords safe from the administrator
One secure way to store and check passwords is as follows:
def change_password user, new_password
salt = random(65536).to_s(16) #will be 4 characters long
password_hash = salt + hash(salt + new_password)
store(user,password_hash)
end
def does_password_match? user, entered_password
correct_password_hash = retrieve(user)
salt = correct_password_hash[0...4]
entered_password_hash = salt + hash(salt + entered_password)
return correct_password_hash == entered_password_hash
end
For the hash function, try to use something strong, and something that doesn't have good rainbow tables in the wild yet. You can change the length of the salt if necessary work around rainbow tables.
Depending on the environment you're in, the variability in your network latency, and whether user names are meant to be publically known, you may want to have another code path compute hash('0000'+entered_password)
if the user doesn't exist, in order to prevent attackers from determining which usernames are valid based on the time it takes determine that the password is incorrect.
Why isn't it used? Because it's a lot of extra work for zero gain. Such a system would not be more secure. It might even be less secure because it gives the false impression of being more secure, leading users to adopt less secure practices (like password reuse, dictionary passwords, etc).
Best Answer
The major mistake you are doing is increasing the opportunity to grab that username/password pair. Even the way SSL works, once authentication has been established, you negotiate a session key for the current collaboration.
The session key is a very important concept, as it can help determine what is a valid session or not. Take the following scenario for example:
If you use the username/password combo for every request the server can't detect which machine is which--particularly if they are behind the same firewall/gateway. Using a session key that is negotiated each time the user logs in the server can detect which session is which. In fact, when it is properly implemented, the old session key is invalidated so that any future requests using that session key fail.
For your session keys make sure that the following apply:
This allows a user to move from one machine to another (logging in fresh on each machine), while doing your diligence to prevent someone stealing their session.