2015-07-03 63 views
11

我正在尝试在我的非MVC .NET Web应用程序中使用Google Calendar API。 (这似乎是一个很重要的区别。)如何为GoogleWebAuthorizationBroker.AuthorizeAsync设置return_uri?

我’试过在Daimto从一些related posts here一些有用的提示一起使用代码this example在谷歌和this example

我写了下面的方法:

public void GetUserCredential(String userName) 
{ 
    String clientId = ConfigurationManager.AppSettings[ "Google.ClientId" ];   //From Google Developer console https://console.developers.google.com 
    String clientSecret = ConfigurationManager.AppSettings[ "Google.ClientSecret" ]; //From Google Developer console https://console.developers.google.com 
    String[] scopes = new string[] { 
      Google.Apis.Calendar.v3.CalendarService.Scope.Calendar   
    }; 

    // here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData% 
    UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets 
    { 
     ClientId = clientId, 
     ClientSecret = clientSecret    
    }, scopes, userName, CancellationToken.None, new FileDataStore("c:\\temp")).Result; 

    // TODO: Replace FileDataStore with DatabaseDataStore 
} 

问题是,当谷歌’小号的OAuth2页面被调用时,redirect_uri不断得到设为http://localhost:<some-random-port>/authorize。我不知道如何将它设置为别的东西,如由AuthorizeAsync产生下面的示例网址:

https://accounts.google.com/o/oauth2/auth?access_type=offline 
    &response_type=code 
    &client_id=********.apps.googleusercontent.com 
    &redirect_uri=http:%2F%2Flocalhost:40839%2Fauthorize%2F 
    &scope=https:%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar 

谷歌与该消息的redirect_uri_mismatch错误页面响应:

“重定向URI在请求:http://localhost:XXXXX/authorize/没有注册重定向URI ”匹配

我只能在我的谷歌开发者’ S控制台铬注册这么多重定向URI ’小号edentials页面。我’ m不倾向于注册65535端口,我想在我的网站上使用除/authorize以外的页面。具体来说,我想在开发过程中使用http://localhost:888/Pages/GoogleApiRedirect,但是我不知道在哪里设置,超出了我在开发人员控制台中所做的工作。

如何明确设置redirect_uri的值?我也接受以“的形式回复此方法是完全错误的。 ”

编辑:

这个过去玩了一天后,我发现,通过使用本机应用程序,而不是Web应用程序客户端ID /客户端秘密,我至少可以拿到到谷歌的网页授权页面,没有它抱怨redirect_uri_mismatch。这仍然是不可接受的,因为它仍然返回到http://localhost:<some-random-port>/authorize,这在我的Web应用程序的控制之外。

+0

你试过配置Visual Studio来使用预定义的端口为您的web应用程序的项目?请查看此文档,以便您可以定义一个端口并在您的开发人员控制台中使用它。 https://msdn.microsoft.com/en-us/library/ms178109(v=vs.140).aspx – Gerardo

+0

感谢您的建议,@Gerardo。是的,它已经为端口888进行了预配置。我还尝试了1024以上的“无特权”端口。我在几种与我的类似的情况下看到了这个建议。如果它确实有效,我想我可以使用'/ authorize'作为我的重定向页面。不是一个理想的解决方案,但我可以忍受。 –

+0

您也可以尝试直接在IIS中部署项目,从那里您可以对Web应用程序的端口进行更多控制。 https://msdn.microsoft.com/en-us/library/vstudio/dd465323(v=vs.100).aspx – Gerardo

回答

10

您可以使用此代码:(从http://coderissues.com/questions/27512300/how-to-append-login-hint-usergmail-com-to-googlewebauthorizationbroker最初的想法)

dsAuthorizationBroker.RedirectUri = "my localhost redirect uri"; 
UserCredential credential = await dsAuthorizationBroker.AuthorizeAsync(... 

dsAuthorizationBroker.cs

using System; 
using System.Collections.Generic; 
using System.Threading; 
using System.Threading.Tasks; 
using Google.Apis.Auth.OAuth2; 
using Google.Apis.Auth.OAuth2.Flows; 
using Google.Apis.Auth.OAuth2.Requests; 
using Google.Apis.Util.Store; 

namespace OAuth2 
{  
    public class dsAuthorizationBroker : GoogleWebAuthorizationBroker 
    { 
     public static string RedirectUri; 

     public new static async Task<UserCredential> AuthorizeAsync(
      ClientSecrets clientSecrets, 
      IEnumerable<string> scopes, 
      string user, 
      CancellationToken taskCancellationToken, 
      IDataStore dataStore = null) 
     { 
      var initializer = new GoogleAuthorizationCodeFlow.Initializer 
      { 
       ClientSecrets = clientSecrets, 
      }; 
      return await AuthorizeAsyncCore(initializer, scopes, user, 
       taskCancellationToken, dataStore).ConfigureAwait(false); 
     } 

     private static async Task<UserCredential> AuthorizeAsyncCore(
      GoogleAuthorizationCodeFlow.Initializer initializer, 
      IEnumerable<string> scopes, 
      string user, 
      CancellationToken taskCancellationToken, 
      IDataStore dataStore) 
     { 
      initializer.Scopes = scopes; 
      initializer.DataStore = dataStore ?? new FileDataStore(Folder); 
      var flow = new dsAuthorizationCodeFlow(initializer); 
      return await new AuthorizationCodeInstalledApp(flow, 
       new LocalServerCodeReceiver()) 
       .AuthorizeAsync(user, taskCancellationToken).ConfigureAwait(false); 
     } 
    } 


    public class dsAuthorizationCodeFlow : GoogleAuthorizationCodeFlow 
    { 
     public dsAuthorizationCodeFlow(Initializer initializer) 
      : base(initializer) { } 

     public override AuthorizationCodeRequestUrl 
         CreateAuthorizationCodeRequest(string redirectUri) 
     { 
      return base.CreateAuthorizationCodeRequest(dsAuthorizationBroker.RedirectUri); 
     } 
    }  
} 
+1

非常感谢。 – FrenkyB

+0

你是否收到带有此代码的令牌? – FrenkyB

+0

这个答案根本没有帮助。没有任何东西可以解释......只是挥舞一根魔杖,让它以某种神秘莫测的方式工作,并不能真正回答原来的问题,即“为什么原始代码不起作用?” – user275801