maysam_p82 Ответов: 2

Почему modelstate. isvalid нажимает на кнопку входа в систему?


это моя модель пользователей:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace Models
{
    public class Users
    {
        [Key]
        public int UserID { get; set; }

        [Required]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Required]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email Address")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Compare("Password")]
        [NotMapped]
        public string ConfirmPassword { get; set; }

        public string PhoneNumber { get; set; }

        [DataType(DataType.DateTime)]
        [Required]
        public DateTime RegistrationDate { get; set; }

       
       
    }



Это мое действие входа в систему:

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(Users user)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    CarDBContext db = new CarDBContext();
                    var getUser = db.Users.Single(p => p.Email == user.Email && p.Password == user.Password);
                    if (getUser != null)
                    {
                        Session["Usr_ID"] = user.UserID.ToString();
                        Session["Email"] = user.Email.ToString();
                        Session["UserName"] = user.FirstName.ToString() + " " + user.LastName.ToString();
                        return RedirectToAction("Index", "Home");
                    }
                    else
                    {
                        ModelState.AddModelError("", "Username or Password does not match.");
                    }
                }
            }
            catch (Exception ex)
            {
                return View("Error", new HandleErrorInfo(ex, "", ""));
            }

            return View();
        }


Это мое действие создать пользователя, которое работает правильно:
[HttpPost]
     public ActionResult CreateUser(Users user)
     {

           if (ModelState.IsValid)
         {
             bool Success = IsUserEmailExist(user.Email);

             if (Success == false)
             {
                 db.Users.Add(user);
                 db.SaveChanges();
                 return RedirectToAction("Index","Home");
             }

             else
             {
                 string err = "The user already exists.";
                 ViewBag.ErrMessage = err;
                 return View();
             }
         }
         return View(user);
     }


Что я уже пробовал:

Я не знаю, почему мой пользователь create работает правильно, но мой логин-нет. Modelstate. isvalid в логине actionresult всегда имеет значение false.
Как я могу написать его с помощью ViewModel?

maysam_p82

Что ты имеешь в виду?

Richard Deeming

Если вы запросите свою базу данных, то увидите пароли своих пользователей в виде обычного текста. Например:

Username: jo.bloggs@test.local
Password: 1L0veS3cureP@ssw0rds!

Это серьезное нарушение безопасности, ожидающее своего часа. Вы должны хранить только соленый хэш пароля, используя уникальную соль для каждой записи. Например:
Username: jo.bloggs@test.local
Salt: 3E800.ABTx519WS9P64
HashedPassword: PHTcY/6cO+nVh+OXMlkgDZiGjPxjnMClHcNPkARZDdv9iYSRNv7Jw==

Когда пользователь пытается войти в систему, вы извлекаете соль, добавляете ее к введенному им паролю, вычисляете его хэш и сравниваете с сохраненным хэшем пароля. Если он совпадает, то пароль правильный. Если нет, то пароль неверный.

Вы должны НИКОГДА иметь возможность видеть фактический пароль пользователя.

maysam_p82

Но я никогда не использовал какой-либо хэш-алгоритм в своем приложении

Richard Deeming

Именно это я и имел в виду. Вы не использовать один. Вы храните пароли в виде обычного текста.

Вам нужно использовать безопасный хэш-алгоритм для безопасного хранения ваших паролей.

maysam_p82

Замечает ли MVC, что если пароль не был хэшем, то он не разрешает Modelstate.Является ли валид правдой?

Richard Deeming

Нет, к сожалению, MVC еще не заставляет вас писать безопасный код. Вы можете ввести как можно больше критические сбои безопасности в ваш код, как вы хотите.

2 Ответов

Рейтинг:
0

Richard Deeming

Вы получаете ошибки проверки, потому что пользователь не вводит каждое отдельное поле из Users класс, когда они входят в систему. Они только вводят свой адрес электронной почты и пароль. Остальные обязательные поля будут пустыми.

Создайте модель представления для действия входа в систему:

public class LoginViewModel
{
    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email Address")]
    public string Email { get; set; }
    
    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel user)
{
   ...
}

ОДНАКО, как я уже упоминал в комментариях, вы должны НИКОГДА храните пароли в виде обычного текста. Храните только соленый хэш пароля, используя уникальную соль для каждой записи.

Безопасная Аутентификация Паролем Объясняется Просто[^]
Соленое хеширование паролей - все правильно[^]

И зачем вы заново изобретаете колесо? ASP.NET имеет несколько совершенно хороших встроенных систем аутентификации - например, Личность ASP.NET [^].


Karthik_Mahalingam

5

Рейтинг:
0

Member 11025896

Привет,
Проблема заключается в модели ваших пользователей, что означает, что при отправке кнопки входа в систему проверка модели проверяет все поля проверки, которые находятся в модели пользователя, но вы передаете только имя пользователя и пароль.
Поэтому вам нужно создать новую модель для входа в систему.

Шаг-1)
публичный класс LoginViewModel
{
[Требуемый]
[DataType(DataType. EmailAddress)]
[Display (Name = " Адрес Электронной Почты")]
публичная строка Email { get; set; }

[Требуемый]
[StringLength(100, ErrorMessage = " длина {0} должна быть не менее {2} символов.", MinimumLength = 6)]
[Тип Данных(DataType.Пароль)]
[Дисплей (Имя = " Пароль")]
public string Password { get; set; }
}

Шаг-2)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(пользователь LoginViewModel)
{
if (ModelState.Функция IsValid)
{
....
}
}

Я надеюсь, что это работает для вас
Счастливое Кодирование=:)


Richard Deeming

Вот что я сказал прошлая неделя[^]!