简体   繁体   中英

Username/Password Database Checking

How can I improve this username/password checking?

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Login(FormCollection collection)
    {
        var users =
            (from p in _dataContext.Users
            where p.Name == collection["Username"] && p.Password == collection["Password"]
             select p);

        if (users.Count() > 0)
        {
            // Login Succeed
            // To get the username I should do something like users.First().Name
            // and that's really bad...

            return RedirectToAction("Login");
        }
        else
        {
            // Login Faild
            return View();
        }
    }

Have you considered Microsoft's Membership API ? It handles all the details of usernames and passwords for you, and in a secure manner. Also, it looks like you plan on storing passwords in the clear, which is a cardinal sin in the realm of cryptography.

  1. Use the asp.net membership model, don't reinvent the wheel.
  2. If you really want to reinvent the wheel, you need salting, and hashed passwords. Only store the hash of the password + salt. This is bare minumum.

I assume there can be only one result from that query. If so, you should use SingleOrDefault :

var user = _dataContext.Users.SingleOrDefault(p =>
                  p.Name == collection["Username"]
                  && p.Password == collection["Password"]);

if(user != null)
{
    // Go on...
    return RedirectToAction("Login");
}
else
{
    // Login Faild
    return View();

}

As others pointed out, there are other problems you should address in that code (namely, not storing plain-text passwords but hashes).

Assuming your 'Username' field is guaranteed to be unique (ie a primary key), just select the user and compare the password field.

Also, you shouldn't generally store the original password in your DB. Instead, shore an MD5 hash or something (using the username as a salt, perhaps). Then compare the hash of the user input to the value in the DB rather than comparing the original value.

Like most people have mentioned, either use the Membership API that is already provided or encrypt the passwords in some secure way. Also, if you decide not to go that route and opt to encrypt passwords, make sure you use an established encryption library that you know works.

Reinventing encryption algorithms can be dangerously flawed (not to mention a waste of time since no value will be added) if they aren't done right. If passwords get leaked, it's not only your site that someone could exploit but potentially many other sites since people tend to use the same username and passwords.

Lastly, use aspnet_regsql.exe at the .Net Command line to configure a database with the schema for the Membership API. It literally takes less than 5 minutes to configure the database and switch your web.config.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM