3

I am using the MVC sample code from google to connect to Google Drive. However I want to implement my own IDataStore so that I can keep user credentials inside my database.

With the FileStorage sample everything works fine and I get the Token and RefreshToken and more than that, it automatically refresh tokens when expired.

Implementing the IDataStore looks easy :

public class MyDataStore : IDataStore
{
    public Task ClearAsync()
    {
        ...
    }

    public Task DeleteAsync<T>(string key)
    {
        ...
    }

    public Task<T> GetAsync<T>(string key)
    {
        ...
    }

    public Task StoreAsync<T>(string key, T value)
    {
        ...
    }
}

So in the StoreAsync I save the credentials on my database, and on the GetAsync I get it from the database.

But strangely when using this I receive the access_token but no refresh_token is returned from Google.

I've tried to search from samples using a custom IDataStore but I can't find anything.

Any ideas?

Thanks a lot

Hugo Hilário
  • 2,848
  • 2
  • 27
  • 43
  • 1
    Have you added "access_type=offline" in the authorization code request when you want the refresh_token? – Dayton Wang Dec 02 '14 at 00:22
  • Every time I call the api I don't receive any refresh token. I only receive the access_token filled. Not sure what do you mean. Thanks – Hugo Hilário Dec 02 '14 at 05:52
  • 1
    UserCredential and AuthorizationCodeFlow take care of automatically "refreshing" the token, which simply means getting a new access token. This is done using a long-lived refresh token, which you receive along with the access token if you use the access_type=offline parameter during the authorization code flow. You may find the information on your sample code url. – Dayton Wang Dec 02 '14 at 06:58
  • @gui47 You led me into the right direction. I searched and found a solution to my issue. I will post it for future reference. Thanks a lot. – Hugo Hilário Dec 02 '14 at 16:13
  • 1
    No problem. Glad to know you get what you want. – Dayton Wang Dec 02 '14 at 16:58
  • You really saved me. Otherwise I was already considering going manually with http calls. Thank YOU – Hugo Hilário Dec 02 '14 at 17:04
  • Could you mark it as right answer? Appreciate it. – Dayton Wang Dec 02 '14 at 17:05
  • I can't because you replied with a comment and not an answer. Don't worry :) – Hugo Hilário Dec 02 '14 at 17:08
  • Well I see, never mind. That's ok. – Dayton Wang Dec 02 '14 at 17:09

1 Answers1

1

Taking in account @gui47 comment I searched on how to add access_type parameter and I found out another post on StackOverflow with the solution:

internal class OfflineGoogleAuthorizationCodeFlow : GoogleAuthorizationCodeFlow
{
    public OfflineGoogleAuthorizationCodeFlow(GoogleAuthorizationCodeFlow.Initializer initializer) : base(initializer) { }

    public override AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUri)
    {
        return new GoogleAuthorizationCodeRequestUrl(new Uri(AuthorizationServerUrl))
        {
            ClientId = ClientSecrets.ClientId,
            Scope = string.Join(" ", Scopes),
            RedirectUri = redirectUri,
            AccessType = "offline",
            ApprovalPrompt = "force"
        };
    }
};

Thank you very much

Community
  • 1
  • 1
Hugo Hilário
  • 2,848
  • 2
  • 27
  • 43