2011-09-17 15 views
23

मैं प्रमाणीकृत उपयोगकर्ता के लिए जानकारी तक पहुंचने के लिए Google+ API का उपयोग करने का प्रयास कर रहा हूं। मैंने नमूनों में से एक से कुछ कोड कॉपी किए हैं, जो ठीक (नीचे) काम करता है, हालांकि मुझे इसे एक तरह से काम करने में परेशानी हो रही है, मैं ऐप-लॉन्च में टोकन का पुन: उपयोग कर सकता हूं।Google+ एपीआई: मेरा ऐप लॉन्च होने पर हर बार एक्सेस का अनुरोध करने से बचने के लिए मैं रीफ्रेशटोकेंस का उपयोग कैसे कर सकता हूं?

मैंने "रीफ्रेश टोकन" संपत्ति को कैप्चर करने और provider.RefreshToken() (अन्य चीजों के साथ) का उपयोग करने और हमेशा 400 Bad Request प्रतिक्रिया प्राप्त करने का प्रयास किया।

क्या कोई यह जानता है कि यह काम कैसे करें, या मुझे पता है कि मुझे कुछ नमूने कहां मिल सकते हैं? Google Code site इस :-(कवर करने के लिए प्रतीत नहीं होता

class Program 
{ 
    private const string Scope = "https://www.googleapis.com/auth/plus.me"; 

    static void Main(string[] args) 
    { 
     var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description); 
     provider.ClientIdentifier = "BLAH"; 
     provider.ClientSecret = "BLAH"; 
     var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthentication); 

     var plus = new PlusService(auth); 
     plus.Key = "BLAH"; 
     var me = plus.People.Get("me").Fetch(); 
     Console.WriteLine(me.DisplayName); 
    } 

    private static IAuthorizationState GetAuthentication(NativeApplicationClient arg) 
    { 
     // Get the auth URL: 
     IAuthorizationState state = new AuthorizationState(new[] { Scope }); 
     state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl); 
     Uri authUri = arg.RequestUserAuthorization(state); 

     // Request authorization from the user (by opening a browser window): 
     Process.Start(authUri.ToString()); 
     Console.Write(" Authorization Code: "); 
     string authCode = Console.ReadLine(); 
     Console.WriteLine(); 

     // Retrieve the access token by using the authorization code: 
     return arg.ProcessUserAuthorization(authCode, state); 
    } 
} 
+0

तुम भी त्रुटि दिखाई दे रहा है जब रीफ्रेश टोकन का उपयोग समाप्ति तिथि से पहले किया जाता है? यदि हां, तो क्या यह संभव है कि आप एक ही बार रीफ्रेश टोकन का उपयोग करने की कोशिश कर रहे हों? –

+0

मुझे वास्तव में पता नहीं है कि मुझे इसका उपयोग कैसे करना है - मैं बस अनुरोध से ताज़ा टोकन को यादृच्छिक रूप से पकड़ रहा था और फिर रीफ्रेश टोकन विधि का उपयोग कर रहा था। मुझे वास्तव में कोई दस्तावेज नहीं मिल रहा है कि इसे कैसे काम करना चाहिए, इसलिए यह संभव है कि मैं इसे गलत तरीके से उपयोग कर रहा था। यही वह है जिसे मैं समझने की कोशिश कर रहा हूं :-( –

+0

@DannyTuppeny क्या आपने इसे हल किया है? यदि नहीं, तो क्या आपने मेरा जवाब देखा है? मुझे आपके जैसा ही समस्या थी, और मुझे गुगलिंग से कोई अच्छा दस्तावेज नहीं मिला, लेकिन मैं मुझे लगता है कि मैंने समस्या हल की है। – poplitea

उत्तर

20

यहां एक उदाहरण है। सुनिश्चित करें कि आप रीफ्रेश टोकन नामक एक स्ट्रिंग सेटिंग जोड़ते हैं और संदर्भ सिस्टम। सुरक्षा या रीफ्रेश टोकन को सुरक्षित रूप से स्टोर करने के लिए एक और तरीका ढूंढें।

private static byte[] aditionalEntropy = { 1, 2, 3, 4, 5 }; 

    private static IAuthorizationState GetAuthorization(NativeApplicationClient arg) 
    { 
     // Get the auth URL: 
     IAuthorizationState state = new AuthorizationState(new[] { PlusService.Scopes.PlusMe.GetStringValue() }); 
     state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl); 

     string refreshToken = LoadRefreshToken(); 
     if (!String.IsNullOrWhiteSpace(refreshToken)) 
     { 
      state.RefreshToken = refreshToken; 

      if (arg.RefreshToken(state)) 
       return state; 
     } 

     Uri authUri = arg.RequestUserAuthorization(state); 

     // Request authorization from the user (by opening a browser window): 
     Process.Start(authUri.ToString()); 
     Console.Write(" Authorization Code: "); 
     string authCode = Console.ReadLine(); 
     Console.WriteLine(); 

     // Retrieve the access token by using the authorization code: 
     var result = arg.ProcessUserAuthorization(authCode, state); 

     StoreRefreshToken(state); 
     return result; 
    } 

    private static string LoadRefreshToken() 
    { 
     return Encoding.Unicode.GetString(ProtectedData.Unprotect(Convert.FromBase64String(Properties.Settings.Default.RefreshToken), aditionalEntropy, DataProtectionScope.CurrentUser)); 
    } 

    private static void StoreRefreshToken(IAuthorizationState state) 
    { 
     Properties.Settings.Default.RefreshToken = Convert.ToBase64String(ProtectedData.Protect(Encoding.Unicode.GetBytes(state.RefreshToken), aditionalEntropy, DataProtectionScope.CurrentUser)); 
     Properties.Settings.Default.Save(); 
    } 
+0

धन्यवाद, इससे बहुत मदद मिली। मैंने Google क्लास स्टोर्डस्टेट क्लाइंट का भी उपयोग किया है उस लिंक में उदाहरण, इसलिए मैं उपयोगकर्ता की जानकारी को उसी "प्राधिकरण" प्रतिक्रिया के साथ पुनर्प्राप्त कर सकता हूं। https://developers.google.com/drive/credentials – IPValverde

11

सामान्य विचार इस प्रकार है:

  1. आप Google की प्राधिकरण Endpoint करने के लिए उपयोगकर्ता अनुप्रेषित

  2. आप एक प्राप्त करते हैं। अल्पकालिक प्राधिकरण कोड

  3. आप Google के उपयोग से लंबे समय तक पहुंचने वाली टोकन के लिए तुरंत प्राधिकरण कोड का आदान-प्रदान करते हैं टोकन एंडपॉइंट। एक्सेस टोकन एक समाप्ति तिथि और रीफ्रेश टोकन के साथ आता है।

  4. आप एक्सेस टोकन का उपयोग करके Google के API को अनुरोध करते हैं।

आप जितनी चाहें उतनी अनुरोधों के लिए एक्सेस टोकन का पुन: उपयोग कर सकते हैं जब तक कि यह समाप्त नहीं हो जाता। फिर आप एक नए एक्सेस टोकन का अनुरोध करने के लिए रीफ्रेश टोकन का उपयोग कर सकते हैं (जो एक नई समाप्ति तिथि और एक नया ताज़ा टोकन के साथ आता है)।

यह भी देखें:

+0

देखें http://stackoverflow.com/questions/ 7454930/google-api-how-can-i-use-refreshtokens-to-Avo-request-access-every-time-my/7489566 # 7489566 –

2

OAuth 2.0 कल्पना अभी तक पूरी नहीं हुई है, और कल्पना कार्यान्वयन से मिलकर बनते हैं विभिन्न ग्राहकों भर में वहाँ बाहर है और ऐसी सेवाएं जो इन त्रुटियों को प्रकट करती हैं। अधिकतर संभावना है कि आप सबकुछ सही कर रहे हैं, लेकिन डॉटनेट ओपेनएथ संस्करण जिसका उपयोग आप ओएथ 2.0 के एक अलग मसौदे को लागू कर रहे हैं, Google वर्तमान में कार्यान्वित कर रहा है। न तो हिस्सा "दाएं" है, क्योंकि spec अभी तक अंतिम रूप में नहीं है, लेकिन यह एक दुःस्वप्न की संगतता बनाता है।

आप देख सकते हैं DotNetOpenAuth संस्करण उपयोग कर रहे नवीनतम है कि, लेकिन अंत में आप या तो तंग बैठने के लिए जब तक चश्मा अंतिम रूप दिया जाता है और हर किसी को सही ढंग से लागू करता है उन्हें आवश्यकता हो सकती है (जैसा भी मामला है कि मदद करता है, जो यह पराक्रम में) , या Google डॉक्स स्वयं को पढ़ें (जो संभावित रूप से OAuth 2.0 के उनके संस्करण का वर्णन करता है) और एक ऐसा कार्यान्वित करता है जो विशेष रूप से उनके ड्राफ़्ट संस्करण को लक्षित करता है।

2

मैं Google के नमूने समाधान में "नमूनाहेल्पर" प्रोजेक्ट को देखने की अनुशंसा करता हूं।नेट क्लाइंट API:

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

3

मैं भी काम करने के लिए हो रही है "ऑफ़लाइन" प्रमाणीकरण के साथ समस्या नहीं थी (यानी प्राप्त:

जो प्राधिकरण की इस विधि का उपयोग पुस्तकालय में नमूने में से एक नीचे पाया जा सकता है ताज़ा टोकन के साथ प्रमाणीकरण), और ओपी के कोड के समान कोड के साथ HTTP-प्रतिक्रिया 400 Bad request मिला। हालांकि, मुझे Authenticate -method में client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(this.clientSecret); लाइन के साथ काम करने के लिए मिला। यह एक कार्य कोड प्राप्त करने के लिए आवश्यक है - मुझे लगता है कि यह लाइन क्लाइंटसेक्रेट को सर्वर पर POST-पैरामीटर के रूप में भेजने के लिए मजबूर करती है (बजाय HTTP मूल Auth-पैरामीटर के रूप में)।

यह समाधान मानता है कि आपके पास पहले से ही क्लाइंट आईडी, क्लाइंट रहस्य और रीफ्रेश-टोकन है। ध्यान दें कि आपको कोड में एक्सेस-टोकन दर्ज करने की आवश्यकता नहीं है। (client.RefreshAuthorization(state); लाइन के साथ लंबे समय तक रहने वाले रीफ्रेश-टोकन भेजते समय Google सर्वर से "हुड के तहत" एक अल्पकालिक पहुंच-कोड प्राप्त किया जाता है। यह एक्सेस-टोकन auth -Variable के हिस्से के रूप में संग्रहीत किया जाता है, जहां से यह "उन्नत" एपीआई-कॉल अधिकृत करने के लिए प्रयोग किया जाता है)

एक कोड उदाहरण है कि अपने Google कैलेंडर तक पहुँचने के लिए गूगल एपीआई v3 के साथ मेरे लिए काम करता है:।

class SomeClass 
{ 

    private string clientID   = "XXXXXXXXX.apps.googleusercontent.com"; 
    private string clientSecret  = "MY_CLIENT_SECRET"; 
    private string refreshToken  = "MY_REFRESH_TOKEN"; 
    private string primaryCal  = "MY_GMAIL_ADDRESS"; 

    private void button2_Click_1(object sender, EventArgs e) 
    { 
     try 
     { 
      NativeApplicationClient client = new NativeApplicationClient(GoogleAuthenticationServer.Description, this.clientID, this.clientSecret); 
      OAuth2Authenticator<NativeApplicationClient> auth = new OAuth2Authenticator<NativeApplicationClient>(client, Authenticate); 

      // Authenticated and ready for API calls... 

      // EITHER Calendar API calls (tested): 
      CalendarService cal = new CalendarService(auth); 
      EventsResource.ListRequest listrequest = cal.Events.List(this.primaryCal); 
      Google.Apis.Calendar.v3.Data.Events events = listrequest.Fetch(); 
      // iterate the events and show them here. 

      // OR Plus API calls (not tested) - copied from OP's code: 
      var plus = new PlusService(auth); 
      plus.Key = "BLAH"; // don't know what this line does. 
      var me = plus.People.Get("me").Fetch(); 
      Console.WriteLine(me.DisplayName); 

      // OR some other API calls... 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Error while communicating with Google servers. Try again(?). The error was:\r\n" + ex.Message + "\r\n\r\nInner exception:\r\n" + ex.InnerException.Message); 
     } 
    } 

    private IAuthorizationState Authenticate(NativeApplicationClient client) 
    { 
     IAuthorizationState state = new AuthorizationState(new string[] { }) { RefreshToken = this.refreshToken }; 

     // IMPORTANT - does not work without: 
     client.ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(this.clientSecret); 

     client.RefreshAuthorization(state); 
     return state; 
    } 
} 
+0

मैं इसे संकलित करने के लिए नहीं प्राप्त कर सकता - API का संस्करण डीएलएल मैंने अभी डाउनलोड किया है क्लाइंटक्र नहीं है NativeWebAplication पर dentialApplicator (क्या मेरे पास अब एपीआई कंसोल में एक गुप्त कुंजी खोजने की क्षमता भी नहीं है ?!) –

+0

आपके पास अपनी कक्षा में 'DotNetOpenAuth.OAuth2 का उपयोग करना' होगा, साथ ही साथ DotNetOpenAuth को डाउनलोड करना होगा: http: //www.dotnetopenauth.net/। 'गुप्त कुंजी' को 'क्लाइंट सीक्रेट' कहा जाता है (यदि यह नहीं है, तो हो सकता है कि आपको अपने क्लाइंट को एपीआई कंसोल में एक बार फिर जोड़ना होगा?) – poplitea

+0

मुझे वास्तव में लार्स ट्रुइजेन्स के उत्तर का उपयोग करके यह काम मिल गया; यह पूरी तरह से पहली बार काम किया :-) –