我正在为我的SPA和ASP.Net Core使用React路由器作为使用Identity进行身份验证的API后端。目前,我正在尝试添加电子邮件确认作为用户注册过程的一部分。困扰我的是如何在不将URL路径硬编码到后端的情况下生成确认URL。
这就是我目前正在使用的:
// Somewhere in my UserService.cs...
// '_urlHelper' is an `IUrlHelper` injected into my service
var routeUrl = _urlHelper.RouteUrl("ConfirmEmail_Route",
new EmailConfirmationRequest { Email = email, Token = token },
requestScheme);
// Send the URL in some nicely formatted email
await _emailSender.SendConfirmationEmail(email, routeUrl);
// My API controller action to handle email confirmation
[HttpPost(Name = "ConfirmEmail_Route")]
public async Task<ActionResult> ConfirmEmail([FromBody] EmailConfirmationRequest payload)
{
var response = await _userService.ConfirmEmail(payload.Token, payload.Email);
...
}
问题是,这会生成一个路径为"的URL/api/auth/ConfirmEmail?电子邮件="但是我的React路由被配置为处理类似于"/确认电子邮件?电子邮件=&";。这意味着,当打开URL时,浏览器显然直接到达API控制器操作,而不是通过我的SPA(忽略该操作需要POST请求的事实(。
所有这些都很有道理,因为_urlHelper.RouteUrl(...)
只看到ASP.Net Core本身中的控制器操作,而对React使用的路由一无所知。我能做的是像这样硬编码:
var routeUrl = $"{requestScheme}://{hostname}/ConfirmEmail?Email={email}&Token={token}";
这不是很通用(我需要考虑如何处理端口号,子域等(。
还有什么好的替代品我还没能找到吗?
编辑2020年12月26日:
我的SPA和API后端的角色似乎有点混乱。更详细地说,这是我在Startup.cs中的设置(使用.Net Core 2.1(:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Other irrelevant setup left out for brevity
// ...
app.UseAuthentication();
// Setup routing
// Specific routes are defined in controllers
app.UseMvc();
app.MapWhen(ctx => ctx.Request.Path.Value.StartsWith("/api"), builder =>
{
builder.UseStatusCodePagesWithReExecute("/api/error/{0}");
});
app.MapWhen(ctx => !ctx.Request.Path.Value.StartsWith("/api"), builder =>
{
builder.UseStatusCodePagesWithReExecute("/error/{0}");
builder.UseMvc(routes =>
{
// For any path not beginning with "/api" return the SPA (Javascript) bundle
routes.MapSpaFallbackRoute("spa-fallback", defaults: new { controller = "Home", action = "Index" });
});
});
}
换句话说:REST API应该被视为一个单独的实体,不关心呈现视图,而只公开在JSON中通信的功能。React SPA是一个捆绑的Javascript文件,负责所有的UI呈现,并与REST API进行通信以进行注册、登录等等。所有这些都使用JWT(令牌(进行身份验证。
这意味着REST API不关心SPA用于在应用程序中导航用户的路径/URL(至少我希望API尽可能不知道客户机/SPA如何处理URL/UI/navigation,但在这种情况下,如果必要,我可能会例外(。因此,后端中没有与React路由SPA中使用的路由匹配的控制器操作,这使得_urlHelper.RouteUrl(...)
变得困难,但我愿意接受建议。
根据您的评论,"我的API后端并不真正知道SPA使用的路线">。我认为你可以要求前端在点击电子邮件中的链接时传递他们想要的URL。
- 用户注册将使用向后端发出POST请求
{
account: xxx
confirmEmailUrl: "https://www.example/confirmEmail"
// Front-end pass what URL they want and create the corresponding page on their side
// So they need to create the page by themselves
}
- 发送电子邮件
var url = "https://www.example/confirmEmail" + userId
SendEmail(url)
因此,当用户收到电子邮件并点击电子邮件中的链接时,它会重定向到前端创建的相应页面,您不需要了解任何前端
3.在前端调用confirm API。
They need to implement this by themselves.
In the confirm page they created when page loaded.
Get userId from query string and call the API you provide