You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:35:25