Google+ API: How can I use RefreshTokens to avoid requesting access every time my app launches?

.net, c#, dotnetopenauth, google-api, google-plus

Solution

Here is an example. Make sure you add a string setting called RefreshToken and reference System.Security or find another way to safely store the refresh token.

    private static byte[] aditionalEntropy = { 1, 2, 3, 4, 5 };

    private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
    {
        // Get the auth URL:
        IAuthorizationState state = new AuthorizationState(new[] { PlusService.Scopes.PlusMe.GetStringValue() });
        state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);

        string refreshToken = LoadRefreshToken();
        if (!String.IsNullOrWhiteSpace(refreshToken))
        {
            state.RefreshToken = refreshToken;

            if (arg.RefreshToken(state))
                return state;
        }

        Uri authUri = arg.RequestUserAuthorization(state);

        // Request authorization from the user (by opening a browser window):
        Process.Start(authUri.ToString());
        Console.Write("  Authorization Code: ");
        string authCode = Console.ReadLine();
        Console.WriteLine();

        // Retrieve the access token by using the authorization code:
        var result = arg.ProcessUserAuthorization(authCode, state);

        StoreRefreshToken(state);
        return result;
    }

    private static string LoadRefreshToken()
    {
        return Encoding.Unicode.GetString(ProtectedData.Unprotect(Convert.FromBase64String(Properties.Settings.Default.RefreshToken), aditionalEntropy, DataProtectionScope.CurrentUser));
    }

    private static void StoreRefreshToken(IAuthorizationState state)
    {
        Properties.Settings.Default.RefreshToken = Convert.ToBase64String(ProtectedData.Protect(Encoding.Unicode.GetBytes(state.RefreshToken), aditionalEntropy, DataProtectionScope.CurrentUser));
        Properties.Settings.Default.Save();
    }

Problem

I'm trying to use the Google+ API to access info for the authenticated user. I've copied some code from one of the samples, which works fine (below), however I'm having trouble making it work in a way I can reuse the token across app-launches. I tried capturing the "RefreshToken" property and using `provider.RefreshToken()` (amongst other things) and always get a `400 Bad Request` response. Does anyone know how to make this work, or know where I can find some samples? The Google Code site doesn't seem to cover this :-( ``` class Program { private const string Scope = "https://www.googleapis.com/auth/plus.me"; static void Main(string[] args) { var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description); provider.ClientIdentifier = "BLAH"; provider.ClientSecret = "BLAH"; var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthentication); var plus = new PlusService(auth); plus.Key = "BLAH"; var me = plus.People.Get("me").Fetch(); Console.WriteLine(me.DisplayName); } private static IAuthorizationState GetAuthentication(NativeApplicationClient arg) { // Get the auth URL: IAuthorizationState state = new AuthorizationState(new[] { Scope }); state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl); Uri authUri = arg.RequestUserAuthorization(state); // Request authorization from the user (by opening a browser window): Process.Start(authUri.ToString()); Console.Write(" Authorization Code: "); string authCode = Console.ReadLine(); Console.WriteLine(); // Retrieve the access token by using the authorization code: return arg.ProcessUserAuthorization(authCode, state); } } ```

Original source