2013-12-18 86 views
2

我們的應用程序需要讓用戶同步他們的谷歌日曆到我們的內部事件模塊,但我堅持做授權並將其存儲到我們的數據庫。我正在關注這個示例Google OAuth以供參考,但是在該示例中,它聲明要實現您自己的使用EF的DataStore,我繼續前進並嘗試了它,但似乎無法使其工作,並且我一直被困在一對夫婦現在幾星期,任何幫助將不勝感激。謝謝!谷歌OAuth數據存儲令牌

我以前是這樣的:

public class TokenDataStore : IDataStore 
{ 
    private readonly IUnitOfWork _unitOfWork; 
    private readonly IUserRepository _userRepository; 
    private readonly IBusinessRepository _businessRepository; 

    public TokenDataStore(IUnitOfWork unitOfWork, IUserRepository userRepository, IBusinessRepository businessRepository) 
    { 
     this._unitOfWork = unitOfWork; 
     this._userRepository = userRepository; 
     this._businessRepository = businessRepository; 
    } 

    //Todo: Add IdataStore Members 

    public static string GenerateStoredKey(string key, Type t) 
    { 
     return string.Format("{0}-{1}", t.FullName, key); 
    } 
} 

一些詳細信息: - MVC 4 -.Net 4.5 - EF 5層 - 谷歌的API

編輯

好的,所以我在過去的幾個小時裏取得了一些進展,終於能夠製作出我自己的AppFlowMetaData

private readonly IAuthorizationCodeFlow flow; 
    private readonly GoogleAPI _API; 
    private readonly IGoogleAPIRepository _googleAPIRepository; 
    private readonly IUnitOfWork _unitOfWork; 

    public AppFlowMetadata(GoogleAPI API, IGoogleAPIRepository googleAPIRepository, IUnitOfWork unitOfWork) 
    { 
     this._API = API; 
     this._googleAPIRepository = googleAPIRepository; 
     this._unitOfWork = unitOfWork; 

     this.flow = 
     new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer 
     { 
      ClientSecrets = new ClientSecrets 
      { 
       ClientId = ConfigurationManager.AppSettings["GP_Key"], 
       ClientSecret = ConfigurationManager.AppSettings["GP_Secret"] 
      }, 
      Scopes = new[] { CalendarService.Scope.Calendar }, 
      DataStore = new TokenDataStore(_API, _googleAPIRepository, _unitOfWork) 
     }); 
    } 

也是我自己的數據存儲類:

private readonly IGoogleAPIRepository _googleAPIRepository; 
    private readonly IUnitOfWork _unitOfWork; 
    private readonly GoogleAPI _model; 

    public TokenDataStore(GoogleAPI model, IGoogleAPIRepository googleAPIRepository, IUnitOfWork unitOfWork) 
    { 
     this._googleAPIRepository = googleAPIRepository; 
     this._unitOfWork = unitOfWork; 
     this._model = model; 
    } 

現在我回電過程中遇到的問題。因此,當用戶使用他們的帳戶登錄時,在我的數據存儲類中,我將該令牌作爲字符串保存在數據庫中,並且當代碼到達從我的模型獲取令牌的部分時,傳遞的數據類型是一個字符串而不是通常的令牌響應。這裏是我的數據存儲的完整代碼:

public class TokenDataStore : IDataStore 
{ 
    private readonly IGoogleAPIRepository _googleAPIRepository; 
    private readonly IUnitOfWork _unitOfWork; 
    private readonly GoogleAPI _model; 

    public TokenDataStore(GoogleAPI model, IGoogleAPIRepository googleAPIRepository, IUnitOfWork unitOfWork) 
    { 
     this._googleAPIRepository = googleAPIRepository; 
     this._unitOfWork = unitOfWork; 
     this._model = model; 
    } 

    public System.Threading.Tasks.Task StoreAsync<T>(string key, T value) 
    { 
     var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value); 
     if(serialized.Contains("access_token")) 
     { 
      _model.TokenString = serialized; 

      _googleAPIRepository.Save(_model, EntityState.Modified); 
      _unitOfWork.Commit(); 
     } 
     return TaskEx.Delay(0); 
    } 

    public System.Threading.Tasks.Task DeleteAsync<T>(string key) 
    { 
     _model.TokenString = ""; 

     _googleAPIRepository.Save(_model, EntityState.Modified); 
     _unitOfWork.Commit(); 

     return TaskEx.Delay(0); 
    } 

    public Task<T> GetAsync<T>(string key) 
    { 
     TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(); 
     try 
     { 
      tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(_model.TokenString)); 
     } 
     catch(Exception ex) 
     { 
      tcs.SetException(ex); 
     } 

     return tcs.Task; 
    } 

    public System.Threading.Tasks.Task ClearAsync() 
    { 
     return TaskEx.Delay(0); 
    } 
} 
+0

你最終能做到嗎?我陷入了同樣的情況。非常感謝 –

+1

嗨雨果,我做了,但我用了一個完全不同的方法..使用HttpWebRequest這個網址:https://accounts.google.com/o/oauth2/token而不是他們的.Net庫.. – Kevin

回答

0

凱文,這是不清楚什麼是不工作..

可能是:

  1. 令牌不被存儲在數據庫中,在以後的時間

訪問用戶資源時

  • 認證是沒有發生我認爲是後者,所以有是您需要解決的兩個挑戰:

    1. 令牌過期正在使數據庫無效
    2. 令牌訪問用戶資源

    事情你需要做的時候沒有被反饋到googleauthenticator是,以確保您能夠使服務器可以訪問的資源訪問脫機而用戶不存在或會話超出範圍。詳情請參閱「脫機訪問」這裏如何做到這一點:Using oAuth for WebApplications

    請務必驗證該令牌餵養它們放回認證時仍然有效。如果不是,則需要使用刷新令牌來更新身份驗證。 Validating token

    您需要確保使用來自您的數據庫的令牌調用googleauthenticator以確保您的代碼具有訪問權限。

    希望我承擔了正確的問題......;)

  • 0

    可以使用FileDataStore(https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.DotNet4/Apis/Util/Store/FileDataStore.cs),存儲其文件中,而不是數據的EntityFramework。

    關於你的問題 - 我沒有得到它,你確切的問題是什麼? 您需要更多關於如何將數據存儲注入流對象的細節?或者你幫助EF? ...請提供更多信息。

    +0

    嗨Peleyal ,那麼,我們使用EF,但我們也使用存儲庫模式和數據依賴注入。所以我想,也許我可以通過我們的存儲庫的接口,所以我可以將令牌存儲在我們的數據庫中。我們使用PaaS來託管我們的應用程序,我不確定我們是否可以存儲文件,但是我會檢查它是否有效。謝謝! – Kevin

    0

    嘗試在您的實體框架存儲庫中存儲具有以下參數的對象。

    public string access_token { get; set; } 
        public string token_type { get; set; } 
        public long? expires_in { get; set; } 
        public string refresh_token { get; set; } 
        public string Issued { get; set; } 
    

    我從其中包含一個實體框架資源庫中的Web API獲取我的令牌。我檢索我的對象作爲JSON字符串。使用Google.Api.Json.NewtonsoftJsonSerializer反序列化Json字符串。

    public Task<T> GetAsync<T>(string key) 
        { 
         TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(); 
         try 
         { 
          string dataStoreView = this.httpClient.Get(uri).ResponseBody; 
    
          tcs.SetResult(Google.Apis.Json.NewtonsoftJsonSerializer.Instance.Deserialize<T>(dataStoreView)); 
         } 
         catch (Exception ex) 
         { 
          tcs.SetException(ex); 
         } 
    
         return tcs.Task; 
        }