【发布时间】:2021-04-03 11:29:00
【问题描述】:
我将 React 路由器用于我的 SPA 和 ASP.Net Core 作为 API 后端,使用 Identity 进行身份验证。目前,我正在尝试将电子邮件确认添加为用户注册过程的一部分。困扰我的是如何在不将 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);
...
}
问题在于,这会生成一个带有类似“/api/auth/ConfirmEmail?Email=...”路径的 URL,但我的 React 路由配置为处理类似“/ConfirmEmail?Email=...”的路径”。这意味着,当打开 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处理 URLs/UI/navigation - 但在这种情况下,如有必要,我可能会例外)。因此,后端中没有与 React 路由 SPA 中使用的路由匹配的控制器操作,这使得_urlHelper.RouteUrl(...) 变得困难,但我愿意接受建议。
【问题讨论】:
-
在前端为确认页面创建一个页面,当用户单击电子邮件中的链接时,将用户重定向到带有令牌广告查询字符串的前端页面。页面加载时,检查查询字符串并将 HTTP 发布到您的 API
-
@MichaelMao 你的意思是控制器动作“确认页面”吗?在那种情况下,我觉得它违背了 SPA 的目的。如果不是,那么如何生成要放入电子邮件的链接,这样它就不会指向我的 API 端点?
-
您是否在 SPA 托管登录和其他注册相关页面?
-
像您的其他 SPA 页面一样生成 URL?
-
@CeemahFour 取决于您所说的“托管”是什么意思。是的,与 UI 相关的所有内容都由 SPA 处理。后端应该是纯 JSON API。因此 JWT 身份验证令牌是由 API 生成的,但 SPA 正在呈现 UI 以供用户输入凭据并基于此获取令牌。
标签: c# reactjs asp.net-core asp.net-core-identity