title: Refreshing access tokens in IdentityServer4 clients
body: <p>I wonder how to refresh a access token in a IdentityServer4 client using the hybrid flow and which is built using ASP.NET Core MVC.</p>
  
  <p>If I have understood the whole concept correctly the client first need to have the "offline_access" scope in order to be able to use refresh tokens which is best practice to enable short lived access tokens and ability to revoke refresh tokens preventing any new access tokens to be issued to the client.</p>
  
  <p>I successfully get a access token and a refresh token, but how should I handle the actual update procedure of the access token in the MVC client?</p>
  
  <p>Can the OpenId Connect (OIDC) middleware handle this automatically? Or should I rather check the expire time of the access token everywhere I call WEB Api's by basically check if the access token have expired or will expire very soon (upcoming 30 seconds) then refresh the access token by calling the token endpoint using the refresh token?</p>
  
  <p>Is it recommended to use the <a href="https://github.com/IdentityModel/IdentityModel2" rel="noreferrer">IdentityModel2</a> library <code>TokenClient</code> extension method <code>RequestRefreshTokenAsync</code> in my Controller action methods for calling the token endpoint?</p>
  
  <p>I have seen code that in the OIDC middleware events request access token and using the response store a claim containing a expire datetime. The problem is that my OIDC in somehow already request a access token automatically so it doesn't feel good to request a new access token directly after recieving the first one.</p>
  
  <p>Example of a Controller action method <strong>without</strong> access token refresh logic:</p>
  
  <pre><code>public async Task&lt;IActionResult&gt; GetInvoices()
      {
          var token = await HttpContext.Authentication.GetTokenAsync("access_token");
  
          var client = new HttpClient();
          client.SetBearerToken(token);
  
          var response = await client.GetStringAsync("http://localhost:5001/api/getInvoices");
          ViewBag.Json = JArray.Parse(response).ToString();
  
          return View();
      }
  </code></pre>