繁体   English   中英

如何自定义 ASP.NET Identity Core 用户名以允许特殊字符和空格

[英]How to customize ASP.NET Identity Core Username to allow special characters and space

我已将注册操作方法更改为接受用户名而不是 Email。

if (ModelState.IsValid)
{
    var user = new ApplicationUser 
    {
        UserName = model.Name,
        Email = model.Email,
    };

但是当我像Joe Smith这样在 TextBox 中输入名称时,它给了我一个错误,即Invalid UserName 它不允许用户名接受空格。 我的问题是如何修改内置用户名以允许空格和特殊字符。 我正在使用 ASP.NET 内核。

提前致谢。

您可以使用 Startup.cs 中的选项设置用户验证规则来配置身份。

services.AddIdentity<ApplicationUser, IdentityRole>(options => {
    options.User.AllowedUserNameCharacters = "allowed characters here";
    options.User.RequireUniqueEmail = true/false;
});

相关资源:

配置身份

所以 cloudikka 的回答是对的。 我将明确添加(cloudikka 的链接也对此进行了解释)您需要列出您想要允许的所有字符(不仅仅是空格或特殊字符),如下所示:

services.AddIdentity<ApplicationUser, IdentityRole>(options => {
    options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+/ ";
});

而不是这个options.User.AllowedUserNameCharacters = " "; 这意味着“只允许空格字符”。 (我认为这是巴巴尔的问题。)

services.AddIdentity<ApplicationUser, IdentityRole>(options => { options.User.AllowedUserNameCharacters = String.Empty; options.User.RequireUniqueEmail = true; })
            .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

如果您有要列入白名单的详尽特殊字符列表,则建议的解决方案可能会很棘手。

如果要改为黑名单,请在 startup.cs 中禁用白名单:

 services.AddIdentity<User, Role>(
                options =>
                {                        
                    options.User.AllowedUserNameCharacters = string.Empty;
                })

然后创建您的自定义用户验证器

 public class UsernameValidator<TUser> : IUserValidator<TUser>
where TUser : User
{
    public Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user)
    {                
        if (user.UserName.Any(x=>x ==':' || x == ';' || x == ' ' || x == ','))
        {
            return Task.FromResult(IdentityResult.Failed(new IdentityError
            {
                Code = "InvalidCharactersUsername",
                Description = "Username can not contain ':', ';', ' ' or ','"
            }));
        }
        return Task.FromResult(IdentityResult.Success);
    }        
}

然后将其添加到startup.cs:

 services.AddIdentity<User, Role>(
                options =>
                {
                    options.Password = new PasswordOptions
                    {
                        RequiredLength = 8,
                        RequireUppercase = true,
                        RequireNonAlphanumeric = true,
                        RequireDigit = true,
                        RequireLowercase = true
                    };
                    options.User.AllowedUserNameCharacters = string.Empty;
                }).AddUserValidator<UsernameValidator<User>>()

这是大多数应用程序开发人员的 en-US 默认思维方式导致的问题之一。

我生成了一个小的 class 像这样为我做这个......

options.User.AllowedUserNameCharacters =Utilities.GetAllWritableCharacters(encoding: System.Text.Encoding.UTF8);

助手 class 包含 GetAllWritableCharacters 方法,如下所示

public class Utilities
{
    public static string GetAllWritableCharacters(Encoding encoding)
    {
        encoding = Encoding.GetEncoding(encoding.WebName, new EncoderExceptionFallback(), new DecoderExceptionFallback());
        var sb= new StringBuilder();
         
        char[] chars = new char[1];
        byte[] bytes = new byte[16];

           
        for (int i = 20; i <=  char.MaxValue; i++)
        {
            chars[0] = (char)i;
            try
            {
                int count = encoding.GetBytes(chars, 0, 1, bytes, 0);

                if (count != 0)
                {
                    sb.Append(chars[0]);
                }
            }
            catch 
            {
                break;
            }
        }
        return sb.ToString();
    }
}

现在您可以接受字符集中所有有意义的字符,包括空格和“奇异”字母

services.AddIdentity<AppUser, AppRole>(opts =>
        {

            opts.User.RequireUniqueEmail = true;
            opts.User.AllowedUserNameCharacters =
            "abcçdefgğhijklmnoöpqrsştuüvwxyzABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ0123456789-._";
            opts.Password.RequiredLength = 4;
            opts.Password.RequireNonAlphanumeric = false;
            opts.Password.RequireLowercase = false;
            opts.Password.RequireUppercase = false;
            opts.Password.RequireDigit = false;
        }).AddPasswordValidator<CustomPasswordValidator>().AddEntityFrameworkStores<AppIdentityDbContext>();

您基本上可以在两个引号之间输入您想要的任何字符。 options.User.AllowedUserNameCharacters = " ";

用户名不应允许特殊字符或空格,我认为没有任何网站允许您这样做,您可以使用名字和姓氏来获取诸如“Joe Smith”之类的信息。

正如@Jaffal 所提到的,用户名不应允许特殊字符或空格。 它应该被视为唯一的用户标识符(又名昵称或电子邮件)。 为了得到很好地显示的用户名,您可能需要引入一个新属性。

例如,添加一个名为Name的新属性,或者在其他一些实现中可能是两个字段GivenNameFamilyName 并要求用户在这些字段中填写她的名字。

要使用额外字段扩展数据库,您的迁移可以是:

public partial class ApplicationUserNamePropertyAdded : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<string>(
            name: "Name",
            table: "AspNetUsers",
            nullable: true);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "Name",
            table: "AspNetUsers");
    }
}

在您使用 ASP.NET Identity 类注册新用户时的代码中,您将有如下代码行:

var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Name = model.Name };

基本上,用户的UserName将始终与 Email 相同,另一个Name属性将用于显示目的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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