.NET Core登录POC开发:同应用REST验证且URL不跳转需求
解决方案实现步骤
要满足点击登录URL不改变、用REST控制器处理验证逻辑的需求,核心是通过AJAX异步提交表单数据到API控制器,而非默认的表单同步提交。以下是具体修改方案:
1. 修改Razor登录页面(Login.cshtml)
移除表单默认的提交行为,添加AJAX脚本处理登录请求,同时保留模型验证和错误提示:
@page @model RazorApp.Pages.Account.LoginModel @{ } <div class="container border" style="padding:20px"> <form id="loginForm"> <div class="text-danger" asp-validation-summary="ModelOnly"></div> <div id="loginError" class="text-danger" style="display:none"></div> <div class="form-group row"> <div class="col-3"> <label asp-for="Credential.Username"></label> </div> <div class="col-5"> <input type="text" asp-for="Credential.Username" class="form-control" /> </div> <div class="text-danger" asp-validation-for="Credential.Username"></div> </div><br /> <div class="form-group row"> <div class="col-3"> <label asp-for="Credential.Password"></label> </div> <div class="col-5"> <input type="password" asp-for="Credential.Password" class="form-control" /> </div> <div class="text-danger" asp-validation-for="Credential.Password"></div> </div> <div class="form-group row"> <div class="col-3"> <button type="button" class="btn btn-primary" id="loginBtn">Login</button> </div> </div> </form> </div> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function() { $("#loginBtn").click(function() { // 清除之前的错误提示 $("#loginError").hide().text(""); // 获取表单数据 var credential = { Username: $("#Credential_Username").val(), Password: $("#Credential_Password").val() }; // 异步提交到API控制器 $.ajax({ url: "/account/login", type: "POST", contentType: "application/json", data: JSON.stringify(credential), success: function(response) { // 登录成功后跳转到首页 window.location.href = "/Index"; }, error: function(xhr) { // 显示登录失败提示 $("#loginError").text("用户名或密码错误").show(); } }); }); }); </script>
2. 完善LoginController(处理认证逻辑)
在API控制器中完成凭证验证后,创建用户身份并生成认证Cookie,确保登录状态有效:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using System.Security.Claims; using RazorApp.Pages.Account; namespace RazorApp { [ApiController] public class LoginController : ControllerBase { [HttpPost] [Route("account/login")] public async Task<IActionResult> Login([FromBody] Credential credential) { // 验证凭证(实际项目中建议使用数据库查询+密码哈希验证) if (credential.Username == "badruddin" && credential.Password == "khan@123") { // 创建用户身份标识 var claims = new List<Claim> { new Claim(ClaimTypes.Name, credential.Username) }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); // 登录用户,生成认证Cookie await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties { IsPersistent = false }); return Ok(); } else { return Unauthorized(); // 返回401表示凭证无效,不要用NotFound } } } }
3. 修正Program.cs的中间件顺序
认证中间件必须放在授权中间件之前,否则认证状态无法被正确识别:
var builder = WebApplication.CreateBuilder(args); // 添加认证服务,使用Cookie认证 builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.Name = "MyCookieAuth"; options.LoginPath = "/Account/Login"; // 指定未授权时跳转的登录页 }); builder.Services.AddRazorPages(); builder.Services.AddControllers(); // 添加API控制器支持 var app = builder.Build(); // 配置请求管道 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // 先启用认证,再启用授权 app.UseAuthentication(); app.UseAuthorization(); // 映射Razor页面和API控制器 app.MapRazorPages(); app.MapControllers(); app.Run();
4. 简化LoginModel.cs(可选)
因为不再使用页面的同步Post提交,可以简化OnPostAsync方法:
using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace RazorApp.Pages.Account { public class Credential { [Required] public string Username { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } } public class LoginModel : PageModel { [BindProperty] public Credential Credential { get; set; } public void OnGet() { } // 保留空方法避免路由错误,或直接删除(若不需要页面Post) public IActionResult OnPostAsync() { return Page(); } } }
关键说明
- 使用AJAX异步提交避免了页面刷新,URL保持不变;
- API控制器负责核心验证和认证逻辑,符合业务逻辑内聚的要求;
- 修正了Program.cs中认证中间件的顺序,确保认证状态能被正确读取;
- 登录成功后通过
SignInAsync生成认证Cookie,维持用户登录状态。
内容的提问来源于stack exchange,提问作者Badruddin
相关产品推荐
相关产品推荐

