我有一个ASP.NET webapi2的API。不是.NET Core。然后我有一个React SPA。我使用Identity和Oauth2。
我正在实施auth系统,密码重置流程让我有点难过。 API将生成通过电子邮件发送给客户端的令牌。然后,客户端单击该链接以在某处导航。
链接导航到客户端javascript应用程序是有意义的,然后从该令牌中获取参数并将其提交给API。这个问题是API必须知道客户端URL才能生成链接。我不希望API知道有关客户端应用程序所在位置的任何信息,因为这似乎是愚蠢的耦合。
另一个选项是密码重置链接直接导航到API,然后再将用户重定向到客户端应用程序。这有一个问题,API需要知道客户端在哪里,它也有这个令人讨厌的重定向黑客。
是否有关于此的资源或有关如何工作的建议?
由于
答案 0 :(得分:1)
我相信您所寻找的是身份提供者"登录"门户。密码重置的流程是身份提供者的一部分,而不是您的主要应用程序。因此,当您的用户单击其密码重置时,它会将其发送到身份提供商密码重置页面(此重置密码链接可能根本不应存在于您的主应用程序中)。一旦重置,用户将登录并使用授权令牌重定向到您的应用程序,您将交换访问令牌。必须为每个想要使用您的身份提供者的应用程序配置重定向。
答案 1 :(得分:0)
WebAPI不会在AccountController中公开所需的方法。
我使用了我添加到AccountController
的这两种方法[Route("ForgotPassword")]
public async Task<IHttpActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = await UserManager.FindByNameAsync(model.UserName) ?? await UserManager.FindByEmailAsync(model.UserName);
if (user == null)
{
return Ok("Ok");
}
if (user.Email == null)
{
throw new InvalidOperationException("Cannot send email. Email address not configured.");
}
var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
#if DEBUG
System.Diagnostics.Process.Start(
string.Format(
"http://localhost:4444/#/forgot-password-reset/{0}/{1}",
HttpUtility.UrlEncode(user.UserName),
HttpUtility.UrlEncode(token)
)
);
#endif
SendMailForgotPassword(user, token);
return Ok("Ok");
}
[Route("ForgotPasswordReset")]
public async Task<IHttpActionResult> ForgotPasswordReset(ForgotPasswordResetViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = await UserManager.FindByNameAsync(model.UserName) ?? await UserManager.FindByEmailAsync(model.UserName);
if (user == null)
{
return Ok("Ok");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Token, model.NewPassword);
if (result.Succeeded)
{
return Ok("Ok");
}
throw new InvalidOperationException(string.Join("\r\n", result.Errors));
}