JSAP

2016-06-08 7 views
7

का उपयोग कर वेबएपीआई 2.0 ओविन टोकन अनुरोध मैंने विजुअल स्टूडियो में एक नया वेबएपीआई समाधान बनाया है और कोड के साथ खेल रहा है और समझने के लिए कोड के साथ खेल रहा हूं।JSAP

मेरे पास एक परीक्षण API है जो सभी को एक प्राधिकरण नियंत्रक और अन्य नियंत्रक के साथ चल रहा है जो सभी वास्तविक कार्यक्षमता लागू करता है।

Content-Type: application/x-www-form-urlencoded 

अन्यथा मैं सिर्फ वापस कोई त्रुटि मिलती है:

नियंत्रकों (एपीआई) JSON प्राप्त और JSON के साथ उत्तर देने/टोकन request.This के अपवाद के साथ, से सब काम हो गया है।

कोड की धारा है कि इस अंतिम बिंदु बनाता है यह प्रतीत होता है:

OAuthOptions = new OAuthAuthorizationServerOptions 
{ 
    TokenEndpointPath = new PathString("/Token"), 
    Provider = new ApplicationOAuthProvider(PublicClientId), 
    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), 
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 
    // In production mode set AllowInsecureHttp = false 
    AllowInsecureHttp = false 
}; 

यह कॉलिंग इस तरह एक 200 सफलता जवाब में यह परिणाम है, एक वाहक टोकन के माध्यम से:

$("#token_button").click(function() 
{ 
    var username = $("#token_email").val(); 
    var password = $("#token_password").val(); 

    postData("Token", "grant_type=password&username=" + username + "&password=" + password, "application/x-www-form-urlencoded", function (data) 
    { 
     user = data; 
     $("#feedback_display").html(user.access_token); 
    }, function() 
    { 
     user = null; 
    }); 
}); 

है जैसे कि यह कॉलिंग इसके परिणामस्वरूप 400 प्रतिक्रियाएं:

$("#token_button").click(function() 
{ 
    var username = $("#token_email").val(); 
    var password = $("#token_password").val(); 

    var data = { 
     "grant_type": "password", 
     "username": username, 
     "password": password 
    } 

    postData("Token", JSON.stringify(data), "application/json", function (data) 
    { 
     user = data; 
     $("#feedback_display").html(user.access_token); 
    }, function() 
    { 
     user = null; 
    }); 
}); 

प्रतिक्रिया निकाय है:

{"error":"unsupported_grant_type"} 

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

कोड/एपीआई/खाता/बाहरी लॉजिक के तहत कोड पर ब्रेकपॉइंट रखने पर कभी हिट नहीं होती है।

क्या इस केवल स्वीकार्य फॉर्म एन्कोडिंग का कोई कारण है? और यदि नहीं तो मैं JSON को स्वीकार करने के लिए नियंत्रक को कैसे बदल सकता हूं?

वैकल्पिक रूप से मैंने अभी कुछ बेवकूफ किया है?

+1

'JSON.stringify (डेटा) ' –

+0

धन्यवाद @ गौवरावस्सार जो अब काम करता है। यदि आप इसे उत्तर के रूप में पोस्ट करते हैं तो मैं सही के रूप में चिह्नित करूंगा। मुझे लगता है कि सवाल उठाता है कि मुझे JSON की आवश्यकता क्यों है। अन्य अंतराल पर पोस्ट किए गए डेटा को पुन: सक्रिय करें, लेकिन वह नहीं? मैंने अभी इसका परीक्षण किया और मुझे इसकी आवश्यकता है। मैं चारों ओर खुदाई करूँगा और देख सकता हूं कि मैं इसे काम नहीं कर सकता हूं। – Morvael

उत्तर

11

application/x-www-form-urlencodedContent-Type के उपयोग के पीछे कारण सरल है: OAuth2 specification (RFC 6749) इस सामग्री प्रकार को टोकन अनुरोधों के लिए आवश्यक है।

कोई अन्य सामग्री-प्रकार OAuth2 अनुपालन क्लाइंट संगतता को तोड़ देगा। मैं सलाह देता हूं कि आप इस मानक व्यवहार को न बदलें।

नोट
कृपया ध्यान दें कि यह:

postData("Token", data, "application/json", function (data) 
{ 
    //... 
} 

काम करता है सिर्फ इसलिए कि आप नहीं JSON भेजने बिल्कुल कर रहे हैं! भले ही आपने application/json को Content-Type हेडर जोड़ा है, तो आपके अनुरोध निकाय को फॉर्म कुंजी-वैल्यू जोड़े (AJAX कॉल में jQuery डिफ़ॉल्ट ऑब्जेक्ट क्रमबद्धता) के रूप में क्रमबद्ध किया गया है।

OAuthAuthorizationServerMiddleware के डिफ़ॉल्ट कार्यान्वयन Microsoft.Owin.Security.OAuth से (अधिक सटीक आंतरिक OAuthAuthorizationServerHandler प्रयुक्त) सिर्फ Content-Type हैडर पर ध्यान नहीं देता और वैसे भी एक फार्म के रूप अनुरोध शरीर को पढ़ने के लिए कोशिश करता है।

+0

व्यापक उत्तर के लिए धन्यवाद। मैंने सत्यापित किया है कि JSON.stringify() का उपयोग नहीं करते समय POST डेटा JSON नहीं है। मैं आपकी सलाह का पालन करूंगा और इसे छोड़ दूंगा, यह सिर्फ थोड़ा सा गेट करता है कि यह एक कॉल फॉर्म और शेष JSON होना चाहिए। – Morvael

+1

लिंक के लिए धन्यवाद। इसने मेरी बहुत मदद की। कभी-कभी यह प्रोटोकॉल परिभाषा को पढ़ने के लिए और अधिक समझ में आता है :) –

1

JSON.stringify(data) कोई डेटा आवश्यकता नहीं है।

+0

मदद के लिए फिर से धन्यवाद, हालांकि अब मैं समझता हूं कि यह क्यों काम करता है और मुझे नहीं लगता कि मैं इसे सही उत्तर के रूप में चिह्नित कर सकता हूं। – Morvael

0

OAuth2 को टोकन अनुरोधों के लिए application/x-www-form-urlencoded सामग्री प्रकार की आवश्यकता है।

फिर भी, मैं इस समाधान के बारे में सोचा:

// GET api/Account/GetToken 
    [HttpPost] 
    [AllowAnonymous] 
    [Route("GetToken")] 
    public async Task<IHttpActionResult> GetToken(TokenRequest request) 
    { 
     var client = new HttpClient() 
     { 
      BaseAddress = new Uri(Request.RequestUri.GetLeftPart(UriPartial.Authority)) 
     }; 

     var content = new FormUrlEncodedContent(new[] 
     { 
      new KeyValuePair<string, string>("grant_type", "password"), 
      new KeyValuePair<string, string>("username", request.Username), 
      new KeyValuePair<string, string>("password", request.Password) 
     }); 

     var result = await client.PostAsync("/token", content); 
     string resultContent = await result.Content.ReadAsStringAsync(); 
     resultContent = resultContent.Replace(".issued", "issued").Replace(".expires", "expires"); 
     TokenResponse tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(resultContent); 

     return Ok(tokenResponse); 
    } 

मॉडल:

public class TokenRequest 
    { 
     public string Username { get; set; } 
     public string Password { get; set; } 
    } 

    public class TokenResponse 
    { 
     public string access_token { get; set; } 
     public string token_type { get; set; } 
     public int expires_in { get; set; } 
     public string userName { get; set; } 
     public DateTime issued { get; set; } 
     public DateTime expires { get; set; } 
     public string error { get; set; } 
     public string error_description { get; set; } 
    } 

यह सुधार किया जा सकता है, लेकिन अच्छा काम करता है।