我正在开发的应用程序具有邮件功能。当我在登录一个多小时后尝试发送邮件时,出现了错误。访问令牌已过期,迫使您重新登录。
但是如何刷新访问令牌呢?我知道我首先必须检查令牌是否已过期,然后发送带有刷新令牌的请求,最后保存返回的访问令牌。
我现在创建了一个中间件并将其应用到 web.php 中的路由,如下所示:
Route::get('create', 'EmployeeController@create')
->middleware('refresh');
然后在中间件中我有以下代码:
public function handle($request, Closure $next)
{
dump(session('user'));
$client = new Google_Client();
$client->setAccessToken(['access_token' => session('user')->token, 'expires_in' => session('user')->expiresIn]);
$_SESSION['token'] = $client->getAccessToken();
$client->setAccessToken($_SESSION['token']);
if( $client->isAccessTokenExpired() ) {
echo "expired";
}
else {
echo "not expired";
}
return $next($request);
}
我知道这并没有达到我想要的效果。但是当我登录时,即使我刚刚登录,它似乎总是回显“过期”。我认为这是因为我没有指定过期日期时间,但我不知道如何设置一个,似乎社交名流只支持这些基本的功能:
$token = $user->token;
$refreshToken = $user->refreshToken; // not always provided
$expiresIn = $user->expiresIn;
我能找到的最接近我的问题的问题是:如何使用 Laravel 管理 OAuth 刷新令牌? 这告诉我添加离线访问,如下所示:
return Socialite::driver('google')->scopes([ 'email', 'profile', 'https://www.googleapis.com/auth/gmail.compose' ])
->with(["access_type" => "offline", "prompt" => "consent select_account"])
->redirect();
但这并没有真正帮助我,因为我不知道从那以后该做什么,或者是否真的有必要。
如果我错过了一些明显的事情或做了一些极其愚蠢的事情,我不会感到惊讶,但我真的在这里碰壁了。
编辑: 我现在意识到,我应该使用 Google API,而不是社交名流,因为我首先使用它来登录。我现在有以下代码:
public function handle($request, Closure $next)
{
dump(session('user'));
$client = new Google_Client();
$client->setAccessToken(['access_token' => session('user')->token, 'expires_in' => session('user')->expiresIn]);
$client->setAccessType('offline');
$refreshToken = Auth::User()->remember_token;
$token = session('user')->token;
$client->revokeToken();
$client->refreshToken($refreshToken);
$newToken=$client->getAccessToken();
echo "old token: <br>" . $token . "<br> New token: <br>";
print_r($newToken);
echo "<br> refreshToken: <br>" . $refreshToken . "<br>" . "client accestoken: <br>";
session('user')->accessToken = $newToken;
print_r(session('user')->accessToken);
dump($client);
return $next($request);
}
但是访问令牌没有改变,为什么不呢?
您可以通过简单地检查该令牌是否已过期并使用刷新令牌来更新访问令牌。这是用于令牌刷新的更新中间件:
public function handle($request, Closure $next)
{
$user = session('user');
if ($user && isset($user->token) && isset($user->refreshToken)) {
$client = new Google_Client();
$client->setAccessToken($user->token);
if ($client->isAccessTokenExpired()) {
$client->refreshToken($user->refreshToken);
$newAccessToken = $client->getAccessToken();
session(['user' => array_merge((array) $user, [
'token' => $newAccessToken['access_token'],
'expiresIn' => $newAccessToken['expires_in'],
'expiresAt' => time() + $newAccessToken['expires_in'],
])]);
}
}
return $next($request);
}