title: Refreshing a Google Token using Google REST API in C#
body: <p>I'm wondering if anyone has solved managing the expiration of Google OAuth2 tokens?</p>
  
  <p>The example below is a REST call to get a list of calendars with a valid token.  If the token is expired, I will get a 401 response and need to refresh the token using the 'refresh token' stored in my database.  I'm wondering if anyone has a strategy around this for their web application?</p>
  
  <pre><code>     var httpContent = new HttpRequestMessage(HttpMethod.Get, "https://www.googleapis.com/calendar/v3/users/me/calendarList");
              httpContent.Headers.Add("Authorization", "OAuth " + token);
              responseBody = client.SendAsync(httpContent).Result.EnsureSuccessStatusCode().Content.ReadAsStringAsync().Result;
  </code></pre>
  
  <p>I've thought about refreshing automatically upon user logging in and saving the refresh token encrypted in session, but not sure if there are any better strategies.</p>
  
  <p>//Notes
  Strategy Options:</p>
  
  <p>1 - Upon Logging a user in, refresh all OAuth tokens for user.  This works assuming that a session will never last longer than a token timeout period. (may not be reliable for all OAuth servers).</p>
  
  <p>2 - When refreshing, use token expiration to record expiration date/time in database.  Before calling any API, check if token needs to be refreshed.  (still need to account for edge case where token expires unexpectedly outside of normal expiration schedule)</p>
  
  <p>3 - Catch the response status of the call and check for 401s.  If receive a 401, refresh the token and try again.  This could be a fail-over for both Options 1/2.  Code for this example would be here:</p>
  
  <pre><code>  var restClient = new RestClient();
          var request = new RestRequest("https://www.googleapis.com/calendar/v3/users/me/calendarList", Method.GET);
          request.AddHeader("Authorization", "OAuth " + token);
  
          // execute the request
          var response = restClient.Execute(request);
          if (response.StatusCode == HttpStatusCode.Unauthorized)
          {
              var newToken = RefreshGoogleToken(token);
              request = new RestRequest("https://www.googleapis.com/calendar/v3/users/me/calendarList", Method.GET);
              request.AddHeader("Authorization", "OAuth " + newToken);
  
              // execute the request
              response = restClient.Execute(request);
          }
          var content = response.Content; // raw content as string
          dynamic responseJson = JsonValue.Parse(content);
  
          var calendarList = new List&lt;GoogleCalendar&gt;();
          foreach (var item in responseJson.items)
          {
              var calendar = new GoogleCalendar { Kind = item.kind, Etag = item.etag, Id = item.id, Title = item.summary, Description = item.description, Location = item.location, Timezone = item.timeZone, SummaryOverride = item.summaryOverride, ColorId = item.colorId, AccessRole = item.accessRole };
              if (item.defaultReminders != null)
              {
                  calendar.DefaultReminders = new List&lt;GoogleCalendarReminder&gt;();
                  foreach (var reminder in item.defaultReminders)
                  {
                      var rem = new GoogleCalendarReminder { Method = reminder.method, Minutes = reminder.minutes };
                      calendar.DefaultReminders.Add(rem);
                  }
              }
  
              calendarList.Add(calendar);
          }
  
          return calendarList;
      }
  </code></pre>