在 asp.net 核心网站 api 中确认电子邮件

Confirm Email in asp.net core web api

此 API 适用于移动应用程序。目标是让用户在注册时确认电子邮件。当用户注册时,会生成确认 link 并通过电子邮件发送。我在 MVC 项目中以同样的方式完成了它,它运行良好,但在 Web API 项目中看起来它不会被削减。 现在,当用户点击 link 时,应该会点击相应的操作方法并完成工作。

唯一的问题是,ConfirmEmail 操作方法在单击确认 link 时没有被触发,尽管它看起来不错。

以下是可能有用的主要配置

MVC 服务配置

services.AddMvc(options => 
                    {  
                        options.EnableEndpointRouting = true;
                        options.Filters.Add<ValidationFilter>();
                    })
                    .AddFluentValidation(mvcConfiguration => mvcConfiguration.RegisterValidatorsFromAssemblyContaining<Startup>())
                    .SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);

身份服务

 public async Task<AuthenticationResult> RegisterAsync(string email, string password)
        {
            var existingUser = await _userManager.FindByEmailAsync(email);

            if(existingUser != null)
            {
                return new AuthenticationResult { Errors = new[] { "User with this email address exists" } };
            }

            // generate user
            var newUser = new AppUser
            {
                Email = email,
                UserName = email
            };

            // register user in system
            var result = await _userManager.CreateAsync(newUser, password);

            if (!result.Succeeded)
            {
                return new AuthenticationResult
                {
                    Errors = result.Errors.Select(x => x.Description)
                };
            }

            // when registering user, assign him user role, also need to be added in the JWT!!!
            await _userManager.AddToRoleAsync(newUser, "User");

            // force user to confirm email, generate token
            var token = await _userManager.GenerateEmailConfirmationTokenAsync(newUser);

            // generate url
            var confirmationLink = _urlHelper.Action("ConfirmEmail", "IdentityController",
                    new { userId = newUser.Id, token = token }, _httpRequest.HttpContext.Request.Scheme);

            // send it per email
            var mailresult = 
                await _emailService.SendEmail(newUser.Email, "BingoApp Email Confirmation",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(confirmationLink)}'>clicking here</a>.");
            if (mailresult)
                return new AuthenticationResult { Success = true };
            else
                return new AuthenticationResult { Success = false, Errors = new List<string> { "Invalid Email Address"} };
        }

控制器

        [HttpPost(ApiRoutes.Identity.Register)]
        public async Task<IActionResult> Register([FromBody] UserRegistrationRequest request)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(new AuthFailedResponse
                {
                    Errors = ModelState.Values.SelectMany(x => x.Errors.Select(xx => xx.ErrorMessage))
                });
            }

            // register the incoming user data with identity service
            var authResponse = await _identityService.RegisterAsync(request.Email, request.Password);          

            if (!authResponse.Success)
            {
                return BadRequest(new AuthFailedResponse
                {
                    Errors = authResponse.Errors
                });
            }

            // confirm registration
            return Ok();
        }


        [HttpGet]
        public async Task<IActionResult> ConfirmEmail(string userId, string token)
        {
            if (userId == null || token == null)
            {
                return null;
            }

            var user = await _userManager.FindByIdAsync(userId);

            if (user == null)
            {
                return null;
            }

            var result = await _userManager.ConfirmEmailAsync(user, token);

            if (result.Succeeded)
            {
               await _emailService.SendEmail(user.Email, "BingoApp - Successfully Registered", "Congratulations,\n You have successfully activated your account!\n " +
                    "Welcome to the dark side.");
            }

            return null;
        }

我觉得你的 _urlHelper.Action(..) 有点可疑。

我不确定您是否应该传递 完整的控制器名称 ,即包括实际单词 controller

试试 _urlHelper.Action("ConfirmEmail", "Identity",

作为提示:我尝试使用 nameof(IdentityController) 来避免像这样的魔法字符串,因为它会 return 没有控制器后缀的控制器名称。