GoogleWebAuthorizationBroker in MVC For Google Drive Access

后端 未结 3 1180
孤独总比滥情好
孤独总比滥情好 2020-12-20 20:33

I\'m stuck trying to access a specific Google drive account from a MVC app. All I need is for the MVC web app to access my google drive scan for a few files and alter the d

3条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-20 21:04

    I got this to work, was able to enable the web site to access Google drive using my account without asking users to login or authorize.

    First of all, follow this link to get Google API work with MVC:

    https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web_applications

    There is a problem in the Sample code, in HomeController

     public async Task IndexAsync(CancellationToken cancellationToken)
    

    Should be:

     public async Task IndexAsync(CancellationToken cancellationToken)
    

    After that, I created a MemoryDataStore (see code at the end) that is a slightly modification from the MemoryDataStore posted here:

    http://conficient.wordpress.com/2014/06/18/using-google-drive-api-with-c-part-2/

    Once you do that, capture the refresh token of the account you are using, and replace the store with this store when authenticate:

        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)
                });
    

    Here commonUser is a predefined user id of your chosen. Please make sure to modify the GetUserID() method to return the same commonUser:

     public override string GetUserId(Controller controller)
        {
            return commonUser;
        }
    

    Once this is done, Google drive will stop asking user to login and authorize the app.

    Here is my MemoryDataStore code:

     /// 
     /// Handles internal token storage, bypassing filesystem
     /// 
    internal class GDriveMemoryDataStore : IDataStore
     {
         private Dictionary _store;
         private Dictionary _stringStore;
    
         //private key password: notasecret
    
         public GDriveMemoryDataStore()
         {
             _store = new Dictionary();
             _stringStore = new Dictionary();
         }
    
         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();
    
             // add new entry
             StoreAsync(key,
                 new TokenResponse() { RefreshToken = refreshToken, TokenType = "Bearer" }).Wait();
         }
    
         /// 
         /// Remove all items
         /// 
         /// 
         public async Task ClearAsync()
         {
             await Task.Run(() =>
             {
                 _store.Clear();
                 _stringStore.Clear();
             });
         }
    
         /// 
         /// Remove single entry
         /// 
         /// 
         /// 
         /// 
         public async Task DeleteAsync(string key)
         {
             await Task.Run(() =>
             {
                // check type
                 AssertCorrectType();
    
                 if (typeof(T) == typeof(string))
                 {
                     if (_stringStore.ContainsKey(key))
                         _stringStore.Remove(key);                 
                 }
                 else if (_store.ContainsKey(key))
                 {
                     _store.Remove(key);
                 }
             });
         }
    
         /// 
         /// Obtain object
         /// 
         /// 
         /// 
         /// 
         public async Task GetAsync(string key)
         {
             // check type
             AssertCorrectType();
    
             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);
         }
    
         /// 
         /// Add/update value for key/value
         /// 
         /// 
         /// 
         /// 
         /// 
         public Task StoreAsync(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);
                 }
             });
         }
    
         /// 
         /// Validate we can store this type
         /// 
         /// 
         private void AssertCorrectType()
         {
             if (typeof(T) != typeof(TokenResponse) && typeof(T) != typeof(string)) 
                 throw new NotImplementedException(typeof(T).ToString());
         }
     }
    

提交回复
热议问题