始终使用HttpResponseMessage 401在ajax帖子上取得成功
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了始终使用HttpResponseMessage 401在ajax帖子上取得成功相关的知识,希望对你有一定的参考价值。
我总是在客户端的ajax帖子上获得statusCode=200
,而服务器用HttpStatusCode.Unauthorized
回答。
我的控制器代码:
public class AccountApiController : ApiController
{
public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]LoginViewModel loginModel)
{
return request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized login.");
}
}
我的ajax代码:
$.ajax({
url: '/api/accountapi/login',
type: 'POST',
data: data
})
.done(function (object, status, xhr) {
alert("Success: " + xhr.status + " : " + xhr.statusText);
})
.always(function (object) {
$("#output").text(JSON.stringify(object, null, 4));
});
结果:使用文本Success: 200 : OK
和输出窗口发出警报:
{
"Message": "Unauthorized login."
}
所以,我可以得到文本错误消息,但我需要让HttpStatusCode来处理错误语句。请帮帮我。
有关此问题的更多信息以及来自Brock Allen的优雅解决方案:http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/
您可能会在返回HttpStatusCode.Unauthorized
后立即通过表单身份验证模块将页面重定向到登录页面。
来自MSDN:
所有未经身份验证的用户都被拒绝访问您的应用程序中的任何页面。如果未经身份验证的用户尝试访问页面,则表单身份验证模块会将用户重定向到由forms元素的loginUrl属性指定的登录页面。
然后,登录页面或其被重定向到的任何页面将以状态代码200提供。
由于返回的状态为200,但用户未获得授权,因此另一个选项是在javascript中检查状态为401的X-Responded-JSON。
.done(function (object, status, xhr) {
if (xhr.getResponseHeader("X-Responded-JSON") != null
&& JSON.parse(xhr.getResponseHeader("X-Responded-JSON")).status == "401") {
//some message here
return;
}
}
详细阐述Valin的评论,以及内联Brock Allen的解决方案。
线索在于返回的OK响应,该响应在内部将重定向捕获到表单登录:
X-Responded-JSON: {"status": 401, "headers": {"location":"http://localhost:50004/Login?ReturnUrl=%2FClient"}}
如果你想修复服务器,而不是抓取这个内部错误状态的响应,你可以使用Brock Allen关于Using cookie authentication middleware with Web API and 401 response codes的文章中的解决方案:
通常在使用cookie身份验证中间件时,当服务器(MVC或WebForms)发出401时,响应将转换为302重定向到登录页面(由CookieAuthenticationOptions上的LoginPath配置)。但是当进行Ajax调用并且响应是401时,将302重定向返回到登录页面是没有意义的。相反,你只是期望返回401响应。不幸的是,这不是我们使用cookie中间件获得的行为 - 响应更改为200状态代码,其中包含带有消息的JSON响应正文:
{"Message":"Authorization has been denied for this request."}
我不确定这项功能的要求是什么。要更改它,您必须通过在cookie身份验证中间件上配置CookieAuthenticationProvider,在有401未经授权的响应时接管对行为的控制:
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnApplyRedirect = ctx => { if (!IsAjaxRequest(ctx.Request)) { ctx.Response.Redirect(ctx.RedirectUri); } } } });
请注意它处理OnApplyRedirect事件。当调用不是Ajax调用时,我们重定向。否则,我们什么都不做,允许401返回给调用者。
只需从katana项目中的helper复制IsAjaxRequest的检查:
private static bool IsAjaxRequest(IOwinRequest request) { IReadableStringCollection query = request.Query; if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest")) { return true; } IHeaderDictionary headers = request.Headers; return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest")); }
以上是关于始终使用HttpResponseMessage 401在ajax帖子上取得成功的主要内容,如果未能解决你的问题,请参考以下文章
何时使用 HttpResponseMessage 和 Request.CreateResponse
如何确定是不是使用 HttpClient 从缓存中完成了 HttpResponseMessage
无法使用 UTF8 编码转换 HttpResponseMessage