title: Keeping user logged in after refresh/using refresh token with Google OAuth2 in React app
body: <p>I’m building a React app where a key part of the functionality is a user can sign into their Google account and then access a feed of their most recent Google Drive/Docs mentions and notifications. A user arrives at my site where I load the Google OAuth2 client with my <code>client_id</code>, <code>apiKey</code>, <code>scope</code> and <code>discoveryDocs</code>, and they can click a button to sign in. For convenience, I’d like the user to not have to re-login and re-auth with their Google account every time they use the app or the app refreshes, I’d like the login information to be saved across sessions. For this I’ll use localStorage to start but eventually integrate a database like Firebase. </p>
  
  <p>After looking through the JavaScript client Google OAuth2 docs I understand how most things work - understand the data and methods stored in the GoogleUser, GoogleAuth, etc objects. I’m having a little trouble with access and refresh tokens. I recognize that you can get the authenticated user’s information through <code>gapi.auth2.getAuthInstance().currentUser.get()</code> and <code>gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse()</code> returns an object with a lot of what I think I need like <code>id_token</code>, <code>access_token</code> and metadata like <code>expires_at</code> and <code>token_type</code>. I also see the <code>grantOfflineAccess()</code> method from which I extract <code>response.code</code>, but I’m not quite sure which of these tokenized strings is the right one to use and how I need to use it. </p>
  
  <p>This FAQ from Google (<a href="https://developers.google.com/api-client-library/javascript/help/faq" rel="nofollow noreferrer">https://developers.google.com/api-client-library/javascript/help/faq</a>) is somewhat helpful but advises to  <code>Refresh the token by calling gapi.auth.authorize with the client ID, the scope and immediate:true as parameters.</code>, but <code>gapi.auth.authorize</code> is noted by Google in the client JS OAuth2 library as being incompatible with the more widely used and heavily documented <code>api.auth2.init</code> and <code>signIn</code>.</p>
  
  <p>I also have a vague idea from posts like <a href="https://stackoverflow.com/questions/36578686/google-oauth2-api-refresh-tokens">Google OAuth2 API Refresh Tokens</a> that I need to follow server-side OAuth2 instructions and I can only get this <code>refresh_token</code> through a server-side call, but I’m still at a bit of a loss. I’ll caveat and say I’m more of a front end developer/designer so I'm shaky on my node and server-side skills.</p>
  
  <p><strong>TL;dr: I don't know how to keep my users who signed in via Google OAuth2 signed in after a refresh. I have an idea it's due to <code>refresh_token</code> and <code>access_token</code> and I have access to them but I don't know what to do after that, in terms of sending data to Google servers, getting information back, and setting the token information for the given user when they return.</strong> </p>
  
  <p>Here's my method that calls on componentDidMount (basically when my app first loads):</p>
  
  <pre><code>loadGoogleClient = () =&gt; {
  
      gapi.load("client:auth2", () =&gt; {
          gapi.auth2.init({
            'client_id': my-client-id,
            'apiKey': my-key,
            'scope': "https://www.googleapis.com/auth/drive.readonly",
            'discoveryDocs': ['https://content.googleapis.com/discovery/v1/apis/drive/v3/rest']
          })
  
              // Listen for sign-in state changes.
          console.log(`User is signed in: ${gapi.auth2.getAuthInstance().isSignedIn.get()}`);
          gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest")
              .then(() =&gt; { console.log("GAPI client loaded for API"); 
                  }, (error) =&gt; { console.error("Error loading GAPI client for API", error); 
              });
      console.log('Init should have worked');
      });
  }
  </code></pre>
  
  <p>And here's my code that's onClick on my Signin button:</p>
  
  <pre><code>authGoogle = () =&gt; {
      gapi.auth2.getAuthInstance()
              .signIn({scope: "https://www.googleapis.com/auth/drive.readonly"})
              .then(function() { console.log("Sign-in successful"); },
                    function(err) { console.error("Error signing in", err); });
  }
  </code></pre>