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(); }
问题原因及解决方案
问题核心原因
- 异步方法未等待:
HttpContext.SignInAsync是异步方法,直接同步调用未使用await,导致认证操作还未完成就执行后续代码。 - 过早检查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,提问作者Мөнхжаргал Р.
相关产品推荐
相关产品推荐

