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

ASP.NET登录按钮需点击两次才生效的问题修复求助

ASP.NET登录功能点击两次才生效问题解决

问题描述

我在ASP.NET项目中开发了登录功能,目标是登录后从登录页面跳转到管理员窗口。但现在遇到问题:输入用户名和密码后点击一次登录按钮无法直接完成登录,必须再次点击才能成功。需要实现输入一次登录信息即可直接登录的功能,请求协助解决。

登录视图代码

<div class="container" id="container">
    <div class="form-container sign-up">
        <form method="post">
            <!--Register action руу post хүсэлт илгээнэ-->
            <h1>Бүртгэл үүсгэх</h1>
            <div class="social-icons">
                <a href="#" class="icon"><i class="fa-brands fa-google-plus-g"></i></a>
                <a href="#" class="icon"><i class="fa-brands fa-facebook-f"></i></a>
                <a href="#" class="icon"><i class="fa-brands fa-github"></i></a>
                <a href="#" class="icon"><i class="fa-brands fa-linkedin-in"></i></a>
            </div>
            <span>дээрх төрөлөөр бүртгүүлэх эсвэл</span>
            <input type="text" placeholder="Name" name="usname">
            <input type="email" placeholder="Email">
            <input type="password" placeholder="Password" name="passwd">
            <button type="submit" asp-action="UserRegister">Бүртгүүлэх</button>
        </form>
    </div>
    <div class="form-container sign-in">
        <form method="post">   <!--Login action руу post хүсэлт илгээнэ-->
            <h1>Нэвтрэх</h1>
            <div class="social-icons">
                <a href="#" class="icon"><i class="fa-brands fa-google-plus-g"></i></a>
                <a href="#" class="icon"><i class="fa-brands fa-facebook-f"></i></a>
                <a href="#" class="icon"><i class="fa-brands fa-github"></i></a>
                <a href="#" class="icon"><i class="fa-brands fa-linkedin-in"></i></a>
            </div>
            <span>дээрх төрлөөр нэвтрэх эсвэл</span>
            <input type="text" placeholder="Username" asp-for="Username"> <!--LoginModel ийн Username руу утга дамжуулна-->
            <input type="password" placeholder="Password" asp-for="Password"> <!--LoginModel ийн Password-->
            <a href="#">Нууц үгээ мартсан уу?</a>
            <button type="submit">Нэвтрэх</button>
            @{
                if (Users.msg == "successUser")
                {
                    <p style="color:green; font-size:1rem; text-align:center;">Амжилттай бүртгэгдэлээ</p>
                }
                else if (Users.msg == "failedUser")
                {
                    <p style="color:red; font-size:1rem; text-align:center">Алдаа гарлаа</p>
                }
            }
        </form>
    </div>
    <!--toggle хийх хэсэг-->
    <div class="toggle-container">
        <div class="toggle">
            <div class="toggle-panel toggle-left">
                <h1>Тавтай морилно уу!</h1>
                <p>Буцаад нэвтрэх хэсэгрүү шилжих</p>
                <button class="hidden" id="login">Нэвтрэх хэсэг</button>
            </div>
            <div class="toggle-panel toggle-right">
                <h1>Сайнуу, Хэрэглэгч!</h1>
                <p>Сайтад бүртгүүлж дараагын холбоосруу нэвтрэхийн тулд бүртгэл үүсгэнэ үү!</p>
                <button class="hidden" id="register">Бүртгүүлэх хэсэг</button>
            </div>
        </div>
    </div>
</div>

控制器Login动作方法

[HttpPost]
public ActionResult Login(LoginViewModel model)
{
    // Validate the user's credentials against your database or any other data store
    Users user = _userRepository.GetUser(model.Username, model.Password);

    if (user != null)
    {
        // Create claims for the authenticated user
        var claims = new List<Claim>
                         {
                             new Claim(ClaimTypes.Name, user.Username),
                             new Claim(ClaimTypes.Role, _userRepository.GetRoleName(user.RoleId)),
                             // Add any additional claims as needed
                         };

        // Create identity with claims
        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

        // Create principal with identity
        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);
        // Sign in the user
        //await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);

        // Make sure the user is signed in before checking roles
        if (User.Identity.IsAuthenticated)
        {
            // Redirect to the originally requested URL or a default URL
            if (User.IsInRole("Admin"))
            {
                return RedirectToAction("Admin", "Account");
            }
            else if (User.IsInRole("User"))
            {
                return RedirectToAction("Userpage", "Account");
            }
        }
    }

    return View();
}

问题原因及解决方案

问题核心原因

  1. 异步方法未等待:HttpContext.SignInAsync是异步方法,直接同步调用未使用await,导致认证操作还未完成就执行后续代码。
  2. 过早检查User对象:当前请求的User.Identity不会在本次请求中更新,认证Cookie要到下一次请求才会被加载,所以第一次点击时User.Identity.IsAuthenticated仍为false,直接返回登录视图;第二次点击时Cookie已存在,才能通过认证检查。

修改后的控制器代码

[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model)
{
    Users user = _userRepository.GetUser(model.Username, model.Password);

    if (user != null)
    {
        var claims = new List<Claim>
                         {
                             new Claim(ClaimTypes.Name, user.Username),
                             new Claim(ClaimTypes.Role, _userRepository.GetRoleName(user.RoleId)),
                         };

        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        // 等待异步认证完成
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);

        // 直接使用从数据库获取的用户角色判断跳转,无需依赖当前请求的User对象
        string roleName = _userRepository.GetRoleName(user.RoleId);
        if (roleName == "Admin")
        {
            return RedirectToAction("Admin", "Account");
        }
        else if (roleName == "User")
        {
            return RedirectToAction("Userpage", "Account");
        }
    }

    return View();
}

关键修改点

  • 将方法返回类型改为async Task<IActionResult>,并添加async关键字。
  • 使用await调用HttpContext.SignInAsync,确保认证操作完成后再执行后续逻辑。
  • 直接使用从数据库获取的user对象的角色信息进行跳转判断,避免依赖当前请求的User对象(该对象在本次请求中不会更新)。

内容的提问来源于stack exchange,提问作者Мөнхжаргал Р.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:17:03