title: Refreshing access tokens with Laravel and Socialite
body: <p>The application I'm working on has a mailing function. When I tried sending a mail more than an hour after logging I was greeted with an error. The access token expired, forcing you to log in again.</p>
  
  <p>But how do I refresh the access token? I know that I first have to check if the token has expired, then send a request with the refresh token and lastly save the access token that is returned.</p>
  
  <p>I have now created a middleware and applied it to a route in web.php, like this:</p>
  
  <pre><code>Route::get('create', 'EmployeeController@create')
                  -&gt;middleware('refresh');
  </code></pre>
  
  <p>Then in the middleware I have the following code:</p>
  
  <pre><code>public function handle($request, Closure $next)
  {
      dump(session('user'));
      $client = new Google_Client();
      $client-&gt;setAccessToken(['access_token' =&gt; session('user')-&gt;token, 'expires_in' =&gt; session('user')-&gt;expiresIn]);
      $_SESSION['token'] = $client-&gt;getAccessToken();
      $client-&gt;setAccessToken($_SESSION['token']);
      if( $client-&gt;isAccessTokenExpired() ) {
        echo "expired";
      }
      else {
        echo "not expired";
      }
      return $next($request);
  }
  </code></pre>
  
  <p>I'm aware that this doesn't do anything even close to what I want. But when I login it always seems to echo 'expired' even when I have just logged in. I think that's because I haven't specified an expiration datetime, but I don't know how to set one seeming as socialite only supports these basic functions: </p>
  
  <pre><code>$token = $user-&gt;token;
  $refreshToken = $user-&gt;refreshToken; // not always provided
  $expiresIn = $user-&gt;expiresIn;
  </code></pre>
  
  <p>The question closest I could find to my problem was this: <a href="https://stackoverflow.com/questions/33988064/how-can-i-manage-oauth-refresh-tokens-with-laravel">How can I manage OAuth refresh tokens with Laravel?</a>
  Which tells me to add offline acces, like this:</p>
  
  <pre><code>return Socialite::driver('google')-&gt;scopes([ 'email', 'profile', 'https://www.googleapis.com/auth/gmail.compose' ])
              -&gt;with(["access_type" =&gt; "offline", "prompt" =&gt; "consent select_account"])
      -&gt;redirect();
  </code></pre>
  
  <p>This doesn't really help me though, as I don't know what to do from there on out, or if it's even really necessary.</p>
  
  <p>I wouldn't be surprised if I missed something obvious or did something incredibly stupid, but I'm really hitting a wall here.</p>
  
  <p>Edit:
  I now realize that instead of socialite I should probably use the Google API since I used that to login in the first place. I now have this following code:</p>
  
  <pre><code>public function handle($request, Closure $next)
  {
    dump(session('user'));
    $client = new Google_Client();
    $client-&gt;setAccessToken(['access_token' =&gt; session('user')-&gt;token, 'expires_in' =&gt; session('user')-&gt;expiresIn]);
    $client-&gt;setAccessType('offline');
    $refreshToken = Auth::User()-&gt;remember_token;
    $token = session('user')-&gt;token;
    $client-&gt;revokeToken();
    $client-&gt;refreshToken($refreshToken);
    $newToken=$client-&gt;getAccessToken();
    echo "old token: &lt;br&gt;" . $token . "&lt;br&gt; New token: &lt;br&gt;";
    print_r($newToken);
    echo "&lt;br&gt; refreshToken: &lt;br&gt;" . $refreshToken . "&lt;br&gt;" . "client accestoken: &lt;br&gt;";
    session('user')-&gt;accessToken = $newToken;
    print_r(session('user')-&gt;accessToken);
    dump($client);
    return $next($request);
  }
  </code></pre>
  
  <p>However the acces token doesn't change, why not?</p>