[英]Confirm Email in asp.net core web api
This API is intended for a mobile application.此 API 适用于移动应用程序。 The goal is to let the user confirm the email upon registration.
目的是让用户在注册时确认 email。 When the user registers, a confirmation link is generated and sent over the email.
当用户注册时,会生成一个确认链接并通过 email 发送。 I've done it the same way in a MVC project, it worked fine, but in a Web API project looks like it ain't gonna cut.
我在 MVC 项目中以同样的方式完成了它,它运行良好,但在 Web API 项目中看起来它不会削减。 Now when the user clicks that link, the respective action method should be hit and do the job.
现在,当用户单击该链接时,应该点击相应的操作方法并完成工作。
The only problem is, the ConfirmEmail action method is just not getting triggered when clicking the confirmation link although it looked fine.唯一的问题是, ConfirmEmail操作方法在单击确认链接时没有被触发,尽管它看起来不错。
Here are the main configurations which might help以下是可能有帮助的主要配置
MVC service configuration MVC 服务配置
services.AddMvc(options =>
{
options.EnableEndpointRouting = true;
options.Filters.Add<ValidationFilter>();
})
.AddFluentValidation(mvcConfiguration => mvcConfiguration.RegisterValidatorsFromAssemblyContaining<Startup>())
.SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0);
Identity Service身份服务
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"} };
}
Controller Controller
[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;
}
Your _urlHelper.Action(..)
looks a bit suspicious to me.您的
_urlHelper.Action(..)
在我看来有点可疑。
I'm not sure you should pass the full controller name , that is, including the actual word controller
.我不确定您是否应该传递完整的 controller name ,即包括实际单词
controller
。
Try _urlHelper.Action("ConfirmEmail", "Identity",
instead.尝试
_urlHelper.Action("ConfirmEmail", "Identity",
而不是。
As a tip: I try to avoid magic strings like these by using nameof(IdentityController)
because it will return the controller name without the controller postfix.提示:我尝试通过使用
nameof(IdentityController)
来避免使用此类魔术字符串,因为它将返回 controller 名称而没有 controller 后缀。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.