2012-07-05 14 views
7

मैं अपने आवेदन में Google कैलेंडर को एकीकृत करने का प्रयास कर रहा हूं और मुझे OAuth प्राधिकरण को रीफ्रेश टोकन से गुज़रने में कुछ समस्याएं आ रही हैं। मुझे कोई समस्या नहीं है, लेकिन रिफ्रेश टोकन संपत्ति शून्य है। देखें लाइन में चिह्नित "त्रुटि यहाँ:" जहाँ मैं इस मुद्देमुझे Google OAuth अनुरोध से रीफ्रेश टोकन क्यों नहीं मिल रहा है?

मेरे Asp.Net MVC नियंत्रक (OAuthController नाम) कर रहा हूँ के लिए निम्नलिखित की तरह दिखता है:

public ActionResult Index() 
    { 
     var client = CreateClient(); 
     client.RequestUserAuthorization(new[] { "https://www.googleapis.com/auth/calendar" }, new Uri("http://localhost/FL.Evaluation.Web/OAuth/CallBack")); 

     return View(); 
    } 

    public ActionResult CallBack() 
    { 

     if (string.IsNullOrEmpty(Request.QueryString["code"])) return null; 

     var client = CreateClient(); 

     // Now getting a 400 Bad Request here 
     var state = client.ProcessUserAuthorization(); 

     // ERROR HERE: The RefreshToken is NULL 
     HttpContext.Session["REFRESH_TOKEN"] = Convert.ToBase64String(Encoding.Unicode.GetBytes(state.RefreshToken)); 

     return JavaScript("Completed!"); 
    } 

    private static WebServerClient CreateClient() 
    { 
     return 
      new WebServerClient(
       new AuthorizationServerDescription() 
        { 
         TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"), 
         AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"), 
         ProtocolVersion = ProtocolVersion.V20 
        } 
       , _GoogleClientId, _GoogleSecret); 
    } 

मैं गूगल के एपीआई दस्तावेजों में देखते हैं, जो मुझे यह सुनिश्चित करने की आवश्यकता है कि access_type अनुरोध किया गया है, जिसे रीफ्रेश टोकन भेजने के लिए offline पर सेट किया गया है। मैं इस मान को अपने प्रमाणीकरण अनुरोध में कैसे सेट करूं?

+0

मैंने अपना कोड नीचे घटा दिया है, और अब मुझे Google से पूछताछ करने का प्रयास करते समय 400 खराब अनुरोध त्रुटि मिल रही है। –

+0

मैंने Google को आगे और आगे HttpRequests को कोडिंग करके मेरी समस्या हल की। मैं कोड को –

उत्तर

12

DotNetOpenAuth के साथ झुकाव के घंटों के बाद और Google APIs नेट के लिए प्रकाशित, मुझे कहीं भी तेज़ नहीं मिला। मैंने पुस्तकालयों को बाधित करने का फैसला किया और मूल HttpRequest और HttpResponse ऑब्जेक्ट्स के साथ Google REST API पर सीधे चला गया। मेरी MVC नियंत्रक के लिए मेरे स्वच्छ कोड इस प्रकार है: इस स्निपेट में कोड का एक बिट के लिए Kelp को

private static string _GoogleClientId = "CLIENT_ID"; 
    private static string _GoogleSecret = "SECRET"; 
    private static string _ReturnUrl = "http://localhost/OAuth/CallBack"; 

    public ActionResult Index() 
    { 
     return Redirect(GenerateGoogleOAuthUrl()); 
    } 

    private string GenerateGoogleOAuthUrl() 
    { 

     //NOTE: Key piece here, from Andrew's reply -> access_type=offline forces a refresh token to be issued 
     string Url = "https://accounts.google.com/o/oauth2/auth?scope={0}&redirect_uri={1}&response_type={2}&client_id={3}&state={4}&access_type=offline&approval_prompt=force"; 
     string scope = UrlEncodeForGoogle("https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.readonly").Replace("%20", "+"); 
     string redirect_uri_encode = UrlEncodeForGoogle(_ReturnUrl); 
     string response_type = "code"; 
     string state = ""; 

     return string.Format(Url, scope, redirect_uri_encode, response_type, _GoogleClientId, state); 

    } 

    private static string UrlEncodeForGoogle(string url) 
    { 
     string UnReservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.~"; 
     var result = new StringBuilder(); 

     foreach (char symbol in url) 
     { 
      if (UnReservedChars.IndexOf(symbol) != -1) 
      { 
       result.Append(symbol); 
      } 
      else 
      { 
       result.Append('%' + String.Format("{0:X2}", (int)symbol)); 
      } 
     } 

     return result.ToString(); 
    } 

    class GoogleTokenData 
    { 
     public string Access_Token { get; set; } 
     public string Refresh_Token { get; set; } 
     public string Expires_In { get; set; } 
     public string Token_Type { get; set; } 
    } 

    public ActionResult CallBack(string code, bool? remove) 
    { 

     if (remove.HasValue && remove.Value) 
     { 
      Session["GoogleAPIToken"] = null; 
      return HttpNotFound(); 
     } 

     if (string.IsNullOrEmpty(code)) return Content("Missing code"); 

     string Url = "https://accounts.google.com/o/oauth2/token"; 
     string grant_type = "authorization_code"; 
     string redirect_uri_encode = UrlEncodeForGoogle(_ReturnUrl); 
     string data = "code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type={4}"; 

     HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest; 
     string result = null; 
     request.Method = "POST"; 
     request.KeepAlive = true; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     string param = string.Format(data, code, _GoogleClientId, _GoogleSecret, redirect_uri_encode, grant_type); 
     var bs = Encoding.UTF8.GetBytes(param); 
     using (Stream reqStream = request.GetRequestStream()) 
     { 
      reqStream.Write(bs, 0, bs.Length); 
     } 

     using (WebResponse response = request.GetResponse()) 
     { 
      var sr = new StreamReader(response.GetResponseStream()); 
      result = sr.ReadToEnd(); 
      sr.Close(); 
     } 

     var jsonSerializer = new JavaScriptSerializer(); 
     var tokenData = jsonSerializer.Deserialize<GoogleTokenData>(result); 
     Session["GoogleAPIToken"] = tokenData.Access_Token; 

     return JavaScript("Refresh Token: " + tokenData.Refresh_Token); 

    } 

बिग धन्यवाद।

+2

कोड के लिए धन्यवाद, यह वास्तव में काम करता है :) –

9

GoogleAuthenticationServer.Description को प्राधिकरण समाप्ति बिंदु URI रखने के लिए समायोजित करें जिसमें क्वेरी स्ट्रिंग में ?access_type=offline शामिल है।

+0

उत्तर के रूप में स्वच्छ कर दूंगा और इस पोस्ट के लिए धन्यवाद 'प्रमाणीकरण सर्वरडिस्क्रिप्शन descServer = Google प्रमाणीकरण सर्वर। विवरण; descServer.AuthorizationEndpoint = new Uri (descServer.AuthorizationEndpoint.ToString() + "access_type = ऑफ़लाइन"); ' ने इसे इस तरह से उपयोग किया और मेरे लिए काम किया – RohitWagh

0

सीधे शब्दों में

AccessType = "ऑफ़लाइन",

GoogleOAuth2AuthenticationOptions करने के लिए() वस्तु जोड़ें।

संबंधित मुद्दे