2013-12-18 18 views
7

Tôi luôn nhận được statusCode=200 trên bài đăng ajax ở phía khách hàng, trong khi máy chủ trả lời với HttpStatusCode.Unauthorized.Luôn thành công trên bài đăng ajax với HttpResponseMessage 401

mã điều khiển của tôi:

public class AccountApiController : ApiController 
{ 
    public HttpResponseMessage Login(HttpRequestMessage request, [FromBody]LoginViewModel loginModel) 
    { 
     return request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized login."); 
    } 
} 

đang ajax của tôi:

$.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)); 
    }); 

Kết quả: cảnh báo với văn bản Success: 200 : OK và cửa sổ đầu ra với:

{ 
    "Message": "Unauthorized login." 
} 

Vì vậy, tôi có thể nhận được văn bản thông báo lỗi, nhưng tôi cần phải nhận được HttpStatusCode để xử lý lỗi các câu lệnh. Làm ơn giúp tôi với.

Thông tin thêm về vấn đề này và giải pháp thanh lịch từ Brock Allen: http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

+0

Sử dụng các công cụ phát triển của bạn để xem các thuộc tính request/response. Trong chrome, hãy chuyển đến tab mạng, thực hiện yêu cầu, kiểm tra URL yêu cầu và Mã trạng thái. –

+1

Tôi nhận được: 'Yêu cầu URL: http: // localhost: 31757/api/accountapi/login Phương thức Yêu cầu: POST Mã Trạng thái: 200 OK' và' X-Trả lời-JSON: {"trạng thái": 401, "tiêu đề ": {" vị trí ":" http: \/\/localhost: 31757 \/Tài khoản \/Đăng nhập? ReturnUrl =% 2Fapi% 2Faccountapi% 2Flogin "}}'. Câu trả lời JSON có vẻ đúng cách để đào bới :) – Valin

Trả lời

6

Nó có thể là trang của bạn được chuyển hướng đến một trang đăng nhập bằng các mô-đun hình thức xác thực ngay khi bạn quay trở lại HttpStatusCode.Unauthorized.

Từ MSDN:

Tất cả người dùng không được thẩm định bị từ chối quyền truy cập vào bất kỳ trang nào trong ứng dụng của bạn. Nếu người dùng chưa được xác thực cố truy cập trang, mô-đun xác thực mẫu chuyển hướng người dùng đến trang đăng nhập được chỉ định bởi thuộc tính loginUrl của phần tử biểu mẫu.

Các trang đăng nhập, hoặc bất cứ trang nó đang được chuyển hướng đến, sau đó được phục vụ với mã trạng thái 200.

+0

Mọi thứ được đặt thành cho phép. Tuy nhiên, trang không được chuyển hướng: ( – Valin

+1

Cũng giống như kiểm tra, hãy thử thay đổi Mã trạng thái thành bất kỳ điều gì khác rồi Unauthorized và xem liệu nó có hoạt động hay không. Tôi lo ngại rằng điều này là do thiết kế trong mô-đun xác thực biểu mẫu –

+0

Tôi nghi ngờ rằng bạn ghi đè tên cho phép bạn trả lại Unauthorize anyways, vì vậy chúng không được cho phép sau khi tất cả, –

6

Bởi vì trạng thái 200 đang được trả lại, nhưng người dùng không được uỷ quyền, tùy chọn khác là để kiểm tra X-Responded-JSON với trạng thái 401 trong javascript của bạn.

.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; 
    } 
} 
0

Để xây dựng dựa trên nhận xét của Valin và giải pháp nội tuyến của Brock Allen.

Các đầu mối nằm trong phản ứng OK trở lại mà nội bẫy chuyển hướng tới một hình thức đăng nhập:

X-Responded-JSON: {"status": 401, "headers": {"location":"http:\/\/localhost:50004\/Login?ReturnUrl=%2FClient"}}

Nếu bạn muốn sửa chữa trên máy chủ, thay vì cào phản ứng đối với tình trạng lỗi nội bộ này , bạn có thể sử dụng giải pháp từ bài viết Brock Allen 's trên Using cookie authentication middleware with Web API and 401 response codes:

Thông thường khi sử dụng xác thực Cookie middleware, khi máy chủ (MVC hoặc WebForms) ra 401, sau đó đáp ứng được chuyển thành 302 lại trực tiếp đến trang đăng nhập (như được cấu hình bởi LoginPath trên CookieAuthenticationOptions). Nhưng khi một cuộc gọi Ajax được thực hiện và phản hồi là 401, sẽ không có nghĩa là trả lại chuyển hướng 302 cho trang đăng nhập. Thay vào đó, bạn chỉ mong đợi phản hồi 401 được trả lại.Rất tiếc, đây không phải là hành vi mà chúng tôi nhận được với phần mềm trung gian cookie - phản hồi được thay đổi thành mã trạng thái 200 có nội dung phản hồi JSON với thông báo:

{"Message":"Authorization has been denied for this request."} 

Tôi không chắc chắn yêu cầu này là gì . Để thay đổi điều đó, bạn phải mất quyền kiểm soát hành vi khi có một 401 phản ứng trái phép bằng cách cấu hình một CookieAuthenticationProvider trên middleware xác thực cookie:

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); 
     } 
    } 
    } 
}); 

Thông báo nó xử lý các sự kiện OnApplyRedirect. Khi cuộc gọi không phải là cuộc gọi Ajax, chúng tôi sẽ chuyển hướng. Nếu không, chúng tôi sẽ không thực hiện thao tác nào cho phép trả lại 401 cho người gọi.

Vui lòng cung cho IsAjaxRequest chỉ đơn giản là sao chép từ một helper trong dự án katana:

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")); 
} 
Các vấn đề liên quan