Валидация пользователя

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 15.12.2019

Кроме проверки пароля в ASP.NET Core Identity также валидируется и пользователь. В частности, если мы введем при регистрации некорректные данные для поля Email, то получим ошибки валидации пользователя:

Валидация пользователя в ASP.NET Core

В данном случае ошибка говорит о том, что email некорректен и должен содержать только алфавитно-цифровые символы.

За валидацию пользователя по умолчанию отвечает класс UserOptions, который определяет следующие свойства:

  • AllowedUserNameCharacters: если равно true, то юзернейм должен содержать только алфавитно-цифровые символы

  • RequireUniqueEmail: если равно true, то email пользователя должен быть уникальным

Для применения этих свойств изменим установку контекста данных в методе ConfigureServices() в классе Startup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<User, IdentityRole>(opts => {
            opts.User.RequireUniqueEmail = true;	// уникальный email
            opts.User.AllowedUserNameCharacters = ".@abcdefghijklmnopqrstuvwxyz"; // допустимые символы
        })
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
}

Свойство opts.User как раз и представляет класс UserOptions.

Этот способ работает, но все же он имеет недостатки:

UserOptions в ASP.NET Core

Несмотря на то, что разрешены только алфавитные символы, в сообщении все равно говорится, что email должен содержать алфавитные или цифровые символы. И во-вторых, сообщения отображаются на английском языке. И в этом случае мы можем полностью переопределить логику валидации, создав свой класс валидатора.

Класс валидатора должен реализовать интерфейс IUserValidator<T>:

public interface IUserValidator<TUser> where TUser : class {
	Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user);
}

Метод ValidateAsync() вызывается при валидации адреса электронной почты. В качестве параметров в метод передаются объект UserManager и валидируемый пользователь.

Теперь создадим класс-валидатор CustomUserValidator:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace CustomIdentityApp.Models
{
    public class CustomUserValidator : IUserValidator<User>
    {
        public Task<IdentityResult> ValidateAsync(UserManager<User> manager, User user)
        {
            List<IdentityError> errors = new List<IdentityError>();

            if (user.Email.ToLower().EndsWith("@spam.com"))
            {
                errors.Add(new IdentityError
                {
                    Description = "Данный домен находится в спам-базе. Выберите другой почтовый сервис"
                });
            }
            if (user.UserName.Contains("admin"))
            {
                errors.Add(new IdentityError
                {
                    Description = "Ник пользователя не должен содержать слово 'admin'"
                });
            }
            return Task.FromResult(errors.Count == 0 ?
                IdentityResult.Success : IdentityResult.Failed(errors.ToArray()));
        }
    }
}

Здесь проверяются пара условий: наличие слова "admin" и домен электронного адреса. В зависимости от результатов проверки добавляются соответствующие ошибки в коллекцию errors. И если ошибок не будет найдено, что значит валидация прошла успешно, и возвращается значение IdentityResult.Success.

Теперь применим наш валидатор. Для этого добавим установку валидатора в метод ConfigureServices() класса Startup:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IUserValidator<User>, CustomUserValidator>();

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<User, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddControllersWithViews();
}

И в этом случае, если мы введем некорректные значения, то увидим сообщения из нашего валидатора:

Создание валидатора пользователя в ASP.NET Core

Также для создания валидатора мы можем унаследовать свой класс от класса UserValidator:

public class CustomUserValidator : UserValidator<User>
{
    public override Task<IdentityResult> ValidateAsync(UserManager<User> manager, User user)
    {
        List<IdentityError> errors = new List<IdentityError>();

        if (user.Email.ToLower().EndsWith("@spam.com"))
        {
            errors.Add(new IdentityError
            {
                Description = "Данный домен находится в спам-базе. Выберите другой почтовый сервис"
            });
        }
        if (user.UserName.Contains("admin"))
        {
            errors.Add(new IdentityError
            {
                Description = "Ник пользователя не должен содержать слово 'admin'"
            });
        }
        return Task.FromResult(errors.Count == 0 ?
            IdentityResult.Success : IdentityResult.Failed(errors.ToArray()));
    }
}

Этот класс также реализует интерфейс IUserValidator, поэтому для его переопределения мы можем изменить метод ValidateAsync(). Результат будет тем же, что и в предыдущем случае.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850