1

I'm using Xamarin.Auth to authenticate the user and have access to the Google Calendar API. I'm able to get an access token and do whatever I need. The problem is the access_token I receive expires after one hour. I looked for examples and information about this in several posts but I'm still not able to ask for new tokens. Here is the code I'm using in my Xamarin.Droid Project:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());

        #region [GoogleAuthentication]

        if (App.auth == null)
        {
            App.auth = new GoogleAuthenticator(App.WebApplicationClientID,
            new Uri("https://www.googleapis.com/plus/v1/people/me"),
            CalendarService.Scope.Calendar);
        }

        // We don't want to have to login every time, so we'll use the Xamarin.Auth AccountStore
        AccountStore store = AccountStore.Create(this);
        Account savedAccount = store.FindAccountsForService("google").FirstOrDefault();
        if (savedAccount != null)
        {
            App.auth.Account = savedAccount;
        }
        else
        {
            App.auth.Completed += (sender, args) =>
            {
                if (args.IsAuthenticated)
                {
                    // Save the account for the future
                    store.Save(args.Account, "google");
                }
            };

            Intent loginIntent = App.auth.GetUI(this);
            StartActivity(loginIntent);
        }

        #endregion [GoogleAuthentication]
    }

The GoogleAuthenticator class implements OAuth2Authenticator as seen below:

public class GoogleAuthenticator
    : OAuth2Authenticator
{
    public GoogleAuthenticator(string clientId, Uri callbackUri, params string[] scopes)
        : base(
            clientId,
            (scopes ?? Enumerable.Empty<string>()).Aggregate(string.Empty, (o, s) => o + " " + s),
            new Uri("https://accounts.google.com/o/oauth2/auth"),
            callbackUri,
            null)
    {
        Completed += (sender, args) =>
        {
            Account = args.Account;
        };
    }

    public Account Account
    {
        get;
        set;
    }

    public void ApplyAuthenticationToRequest(HttpWebRequest request)
    {
        if (Account == null)
            throw new InvalidOperationException("You must be authenticated to make requests");

        string token = Account.Properties["access_token"];
        string type = Account.Properties["token_type"];
        request.Headers[HttpRequestHeader.Authorization] = String.Format("{0} {1}", type, token);
    }
}

I tried changing the authorizationUrl adding the parameters approval_prompt=force and access_type=offline but it didn't work too.

How can I get the refresh_token using Xamarin.Auth?

Thanks.

Daniel Kern
  • 41
  • 1
  • 4
  • I have no experience with it, but I think this link provides a great explanation about it: https://lostechies.com/jimmybogard/2014/11/13/mobile-authentication-with-xamarin-auth-and-refresh-tokens/ basically, the GetInitialUrlAsync method is overriden, a RequestRefreshTokenAsync method is created and called. Check if it works for you. – Luis Beltran Apr 30 '16 at 08:59
  • Hi Luis, thanks. I saw this link but it didn't help me understanding the problem. – Daniel Kern May 02 '16 at 04:24

2 Answers2

1

Have you seen this sample code here it looks like you can get the refresh Token from the account object you get back:

CurrentUser.Properties["refresh_token"]

current user is set here

so in you code it would just be:

Account.Properties["refresh_token"];

Also this question is similiar Xamarin.Auth with Google APIs: Renew credentials?

Community
  • 1
  • 1
Iain Smith
  • 9,230
  • 4
  • 50
  • 61
  • Hi Iain. Thanks for your response and help. The problem is I never get a **refresh_token**. All answers and posts I saw about this issue assume I get a refresh_token. – Daniel Kern May 02 '16 at 04:22
0

The documentation can be found here: https://developers.google.com/identity/protocols/OAuth2InstalledApp In the constructor of OAuth2Authenticator you pass in null as a accessTokenUrl. Therefore I guess your library cannot get past Step 5, the exchange of the authorization code for refresh and access tokens.

manuel
  • 252
  • 1
  • 9