ASP.NET中Ajax调用触发AspNetUser自动登出问题求助
看起来你遇到了一个挺头疼的场景:登录AspNetUser后,选下拉框触发Ajax提交瞬间就登出,但未登录时功能完全正常。结合你的代码,我梳理了几个最可能的原因和对应的修复方案:
1. 防伪令牌(AntiForgery Token)缺失或未正确携带
虽然你的IndexAjax加了[AllowAnonymous],但如果项目全局启用了防伪验证(比如Web.config里开了ValidateAntiForgeryTokenOnAllPosts=true),所有POST请求都需要携带__RequestVerificationToken,否则会被服务器拒绝,表现为身份验证失效(自动登出)。
而你用Ajax.BeginForm的时候,虽然默认会生成这个令牌,但手动触发表单提交可能存在令牌未被正确传递的情况。
修复方法:
- 手动在表单内添加防伪令牌,确保它能被正确提交:
@using (Ajax.BeginForm("IndexAjax", "Wedstrijd", new AjaxOptions { InsertionMode = InsertionMode.Replace, HttpMethod = "POST", LoadingElementId = "ajax-loader", UpdateTargetId = "searchresults", })) { <div class="form-horizontal"> @Html.AntiForgeryToken() <!-- 手动添加这一行 --> <div class="form-group"> @Html.Label("Ploeg", htmlAttributes: new { @class = "control-label col-md-1" }) <div class="col-md-10"> @Html.DropDownList("PloegId", null, "---Kies ploeg---", htmlAttributes: new { @class = "form-control" }) <img id="ajax-loader" src="@Url.Content("~/content/Images/ajax-loader.gif")" style="display: none" /> </div> </div> </div> } - 同时给
IndexAjaxAction加上[ValidateAntiForgeryToken]特性,确保服务器验证令牌:[AllowAnonymous] [HttpPost] [ValidateAntiForgeryToken] public ActionResult IndexAjax(int? ploegId) { // 现有代码保持不变 }
2. 请求方法不匹配引发的验证异常
你在AjaxOptions里设置了HttpMethod = "POST",但你的IndexAjaxAction默认是接受GET请求的(没有加[HttpPost]特性)。这种请求方法不匹配的情况,可能会触发ASP.NET身份验证的异常,导致登出。
修复方法:
要么把AjaxOptions里的HttpMethod改成"GET",要么给IndexAjax加上[HttpPost]特性(上面的方案已经包含了这一步)。
3. 身份验证Cookie的SameSite属性配置问题
如果你的项目用的是较新的ASP.NET版本,身份验证Cookie的SameSite属性设置不当,会导致Ajax请求时Cookie无法被正确携带,服务器识别不到登录状态,从而触发登出。
修复方法:
在Web.config里配置Cookie的SameSite属性:
<system.web> <authentication mode="Forms"> <forms name=".ASPXAUTH" loginUrl="~/Account/Login" timeout="2880" sameSite="None" requireSSL="false" /> </authentication> </system.web>
如果你的网站是HTTPS部署,记得把requireSSL改成true,更安全。
4. 手动触发表单提交的方式问题
你用$("form").trigger("submit");触发提交,有时候会绕过Unobtrusive Ajax的逻辑,变成普通的表单提交,而不是Ajax请求,这会导致页面跳转或者身份验证上下文丢失。
修复方法:
换成手动用jQuery发送Ajax请求,精准控制参数和令牌:
$("#PloegId").on("change", function() { var ploegId = $(this).val(); var token = $("input[name='__RequestVerificationToken']").val(); $("#ajax-loader").show(); $.ajax({ url: '@Url.Action("IndexAjax", "Wedstrijd")', type: 'POST', data: { PloegId: ploegId, __RequestVerificationToken: token }, success: function(result) { $("#searchresults").html(result); }, complete: function() { $("#ajax-loader").hide(); } }); });
这种方式能确保所有必要参数都被正确发送,避免Unobtrusive Ajax的潜在问题。
最后排查建议
打开浏览器开发者工具(F12),切换到Network标签,观察触发下拉框后的请求:
- 看请求状态码:如果是403 Forbidden,基本就是防伪令牌的问题;
- 看Request Headers里有没有
.ASPXAUTHCookie(Forms验证场景); - 看Form Data里有没有
__RequestVerificationToken参数。
内容的提问来源于stack exchange,提问作者wolfvandenkush

