2013-12-18 12 views
7

के साथ AJAX पोस्ट पर हमेशा सफलता मुझे ग्राहक पक्ष पर AJAX पोस्ट पर statusCode=200 मिलता है, जबकि सर्वर HttpStatusCode.Unauthorized के साथ उत्तर देते हैं।HttpResponseMessage 401

मेरे नियंत्रक कोड:

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 प्राप्त करने की आवश्यकता है बयान। कृपया मेरी मदद करें।

इस मुद्दे और ब्रॉक एलन से सुरुचिपूर्ण समाधान के बारे में अधिक जानकारी: http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

+0

अनुरोध/प्रतिक्रिया गुण देखने के लिए अपने डेवलपर उपकरण का प्रयोग करें। क्रोम में नेटवर्क टैब पर जाएं, अनुरोध करें, अनुरोध यूआरएल और स्टेटस कोड का निरीक्षण करें। –

+1

मुझे मिला: 'अनुरोध यूआरएल: http: // localhost: 31757/api/accountapi/लॉगिन अनुरोध विधि: POST स्थिति कोड: 200 ठीक' और 'एक्स-प्रतिसाद-जेएसओएन: {" स्थिति ": 401," हेडर ": {" स्थान ":" http: \/\/स्थानीय होस्ट: 31757 \/खाते \/लॉग इन ReturnUrl =% 2Fapi% 2Faccountapi% 2Flogin "}}'। JSON उत्तर में खोदने का सही तरीका दिखता है :) – Valin

उत्तर

6

यह हो सकता है कि आपके पृष्ठ रूपों प्रमाणीकरण मॉड्यूल द्वारा एक प्रवेश पृष्ठ पर रीडायरेक्ट हो रहा जैसे ही आप HttpStatusCode.Unauthorized लौट आते हैं।

MSDN से:

सभी अप्रमाणित उपयोगकर्ताओं को अपनी आवेदन में किसी भी पृष्ठ के लिए उपयोग से वंचित हैं। यदि एक अनधिकृत उपयोगकर्ता किसी पृष्ठ तक पहुंचने का प्रयास करता है, तो प्रपत्र प्रमाणीकरण मॉड्यूल उपयोगकर्ता को लॉगऑन पृष्ठ पर लॉग इन करता है जो फॉर्म तत्व के loginUrl विशेषता द्वारा निर्दिष्ट किया गया है।

प्रवेश पृष्ठ, या जो कुछ भी पेज यह करने के लिए है, तो स्थिति कोड 200

+0

सबकुछ अनुमति देने के लिए सेट है। लेकिन पृष्ठ वैसे भी रीडायरेक्ट नहीं कर रहा है :( – Valin

+1

बस एक परीक्षण के रूप में, किसी भी अन्य स्थिति में स्टेटसकोड को बदलने का प्रयास करें और अनधिकृत है और देखें कि यह काम करता है या नहीं। मुझे डर है कि यह फॉर्म प्रमाणीकरण मॉड्यूल में डिज़ाइन द्वारा है। –

+0

मुझे संदेह है कि आप allowanonymous को ओवरराइड करते हैं आप किसी भी तरह से अनधिकृत वापस लौटते हैं, इसलिए उन्हें सभी के बाद अनुमति नहीं है। –

6

साथ परोसा जाता है क्योंकि 200 का स्थिति लौटा जा रही है, लेकिन उपयोगकर्ता अधिकृत नहीं है पुनः निर्देशित किया जा रहा है, एक और विकल्प है अपने जावास्क्रिप्ट में 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; 
    } 
} 
0

वैलिन की टिप्पणी और इनलाइन ब्रॉक एलन के समाधान पर विस्तार करने के लिए।

सुराग लौटे ठीक प्रतिक्रिया जो आंतरिक रूप से एक फार्म लॉगिन करने के लिए पुन: निर्देशन फंसा लेती है में निहित है:

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

आप के बजाय इस आंतरिक त्रुटि राज्य के लिए प्रतिक्रिया स्क्रैप की, सर्वर पर ठीक करने के लिए करना चाहते हैं , आप Using cookie authentication middleware with Web API and 401 response codes पर ब्रॉक एलन के लेख से समाधान का उपयोग कर सकते हैं: जब सर्वर (MVC या WebForms) एक 401 जारी करता है, जब कुकी प्रमाणीकरण मिडलवेयर का उपयोग कर

आम तौर पर, तो प्रतिक्रिया एक 302 में बदल जाती है फिर से लॉगिन पृष्ठ पर सीधे (जैसा कि CookieAuthenticationOptions पर लॉगिनपैथ द्वारा कॉन्फ़िगर किया गया है)। लेकिन जब एक अजाक्स कॉल किया जाता है और प्रतिक्रिया 401 होती है, तो लॉगिन पृष्ठ पर 302 रीडायरेक्ट वापस करने का अर्थ नहीं होगा। इसके बजाय आप केवल 401 प्रतिक्रिया वापस आने की उम्मीद करेंगे।दुर्भाग्य से इस व्यवहार हम कुकी मिडलवेयर के साथ नहीं है - प्रतिक्रिया एक संदेश के साथ एक JSON प्रतिक्रिया शरीर के साथ 200 स्थिति कोड के लिए बदल जाता है:

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

मुझे यकीन है कि क्या आवश्यकता इस सुविधा के लिए था नहीं कर रहा हूँ । यह बदलने के लिए, आप जब वहाँ कुकी प्रमाणीकरण मिडलवेयर पर एक 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 घटना को संभालती है। जब कॉल अजाक्स कॉल नहीं होता है, तो हम रीडायरेक्ट करते हैं। अन्यथा, हम कुछ भी नहीं करते हैं जो 401 को कॉलर पर वापस आने की अनुमति देता है।

IsAjaxRequest के लिए चेक बस कटाना परियोजना में एक helper से नकल है:

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")); 
} 
संबंधित मुद्दे