c# - 在 asp.net core web api 中确认电子邮件
问题描述
此 API 适用于移动应用程序。目标是让用户在注册时确认电子邮件。当用户注册时,会生成一个确认链接并通过电子邮件发送。我在 MVC 项目中以同样的方式完成了它,它运行良好,但在 Web API 项目中看起来它不会削减。现在,当用户单击该链接时,应该点击相应的操作方法并完成工作。
唯一的问题是,ConfirmEmail操作方法在单击确认链接时没有被触发,尽管它看起来不错。
以下是可能有帮助的主要配置
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)
因为它会返回没有控制器后缀的控制器名称。
推荐阅读
- javascript - 为什么从地图获取比从对象获取慢?
- python - 从内到外增加numpy数组中的值
- typescript - 如何从函数的默认值推断类型?
- ios - 如何允许用户根据两个条件进行搜索
- r - 根据列表计算关键字的数量
- android - 有没有办法在android中更改我的应用程序的布局方向
- json - 在 JQ 中使用 JSON 键作为查找
- c++ - Qt3D 我可以列出来自 Qt3DRender::QGeometryRenderer 的所有顶点吗?
- spring-batch - 步骤 ExecutionContext 未在 Spring Cloud Data Flow 上使用 Spring Cloud Task 提升
- assembly - 为什么这个 asm strcmp() 返回错误的值