我一直试图从MVC应用程序访问特定的Google云端硬盘帐户.我只需要MVC网络应用程序访问我的谷歌驱动器扫描几个文件,并根据谷歌驱动器的内容更改数据库.问题是当在IIS中运行时,无法对驱动器进行身份验证,因为GoogleWebAuthorizationBroker尝试打开浏览器,如果它是一个
Windows应用程序,但似乎无法通过IIS执行此操作,即使它确实是服务器端.
理想情况下,我根本不需要对这个应用程序进行身份验证,但是如果它已经完成了,那么我如何让它在IIS中运行?
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets { ClientId = "MY_ID",ClientSecret = "My_Secret" },new[] { DriveService.Scope.Drive },"user",CancellationToken.None,dataStore: new FileDataStore(Server.MapPath("~/app_data/googledata"))).Result;
解决方法
我得到了这个工作,能够让网站使用我的帐户访问谷歌驱动器,而无需用户登录或授权.
首先,请点击此链接以使Google API与MVC一起使用:
https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web_applications
HomeController中的示例代码存在问题
public async Task IndexAsync(CancellationToken cancellationToken)
应该:
public async Task<ActionResult> IndexAsync(CancellationToken cancellationToken)
之后,我创建了一个MemoryDataStore(参见最后的代码),这是对这里发布的MemoryDataStore的一点修改:
http://conficient.wordpress.com/2014/06/18/using-google-drive-api-with-c-part-2/
执行此操作后,捕获正在使用的帐户的刷新令牌,并在进行身份验证时将商店替换为此商店:
private static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = clientID,ClientSecret = clientSecret },Scopes = new[] { DriveService.Scope.Drive },//DataStore = new FileDataStore("Drive.Api.Auth.Store") DataStore = new GDriveMemoryDataStore(commonUser,refreshToken) });
这里commonUser是您选择的预定义用户ID.请确保修改GetUserID()方法以返回相同的commonUser:
public override string GetUserId(Controller controller) { return commonUser; }
完成此操作后,Google云端硬盘将停止要求用户登录并授权该应用.
这是我的MemoryDataStore代码:
/// <summary> /// Handles internal token storage,bypassing filesystem /// </summary> internal class GDriveMemoryDataStore : IDataStore { private Dictionary<string,TokenResponse> _store; private Dictionary<string,string> _stringStore; //private key password: notasecret public GDriveMemoryDataStore() { _store = new Dictionary<string,TokenResponse>(); _stringStore = new Dictionary<string,string>(); } public GDriveMemoryDataStore(string key,string refreshToken) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key"); if (string.IsNullOrEmpty(refreshToken)) throw new ArgumentNullException("refreshToken"); _store = new Dictionary<string,TokenResponse>(); // add new entry StoreAsync<TokenResponse>(key,new TokenResponse() { RefreshToken = refreshToken,TokenType = "Bearer" }).Wait(); } /// <summary> /// Remove all items /// </summary> /// <returns></returns> public async Task ClearAsync() { await Task.Run(() => { _store.Clear(); _stringStore.Clear(); }); } /// <summary> /// Remove single entry /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public async Task DeleteAsync<T>(string key) { await Task.Run(() => { // check type AssertCorrectType<T>(); if (typeof(T) == typeof(string)) { if (_stringStore.ContainsKey(key)) _stringStore.Remove(key); } else if (_store.ContainsKey(key)) { _store.Remove(key); } }); } /// <summary> /// Obtain object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public async Task<T> GetAsync<T>(string key) { // check type AssertCorrectType<T>(); if (typeof(T) == typeof(string)) { if (_stringStore.ContainsKey(key)) return await Task.Run(() => { return (T)(object)_stringStore[key]; }); } else if (_store.ContainsKey(key)) { return await Task.Run(() => { return (T)(object)_store[key]; }); } // key not found return default(T); } /// <summary> /// Add/update value for key/value /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public Task StoreAsync<T>(string key,T value) { return Task.Run(() => { if (typeof(T) == typeof(string)) { if (_stringStore.ContainsKey(key)) _stringStore[key] = (string)(object)value; else _stringStore.Add(key,(string)(object)value); } else { if (_store.ContainsKey(key)) _store[key] = (TokenResponse)(object)value; else _store.Add(key,(TokenResponse)(object)value); } }); } /// <summary> /// Validate we can store this type /// </summary> /// <typeparam name="T"></typeparam> private void AssertCorrectType<T>() { if (typeof(T) != typeof(TokenResponse) && typeof(T) != typeof(string)) throw new NotImplementedException(typeof(T).ToString()); } }