请求的身份验证范围不足 - gmail api 离线无法使用刷新令牌

Request had insufficient authentication scopes - gmail api offline not working refresh token

在我的应用程序中,用户登录 Google Api 以将指定邮件从 gmail 同步到我的应用程序。当用户登录到该应用程序时,它会工作约一周,此后刷新令牌将过期,用户必须再次登录,但当他们再次登录时,api 无法正常工作并出现 return 错误。

Message: { "error": { "code": 403, "message": "Request had insufficient authentication scopes.", "errors": [ { "message": "Insufficient Permission", "domain": "global", "reason": "insufficientPermissions" } ], "status": "PERMISSION_DENIED" } }

代码:

include_once 'vendor/autoload.php';

                    foreach($officesList as $office)
                    {
                        #$this->debug(2, 'cronGmail', 'step2 execution');
                        $googleClient = new Google_Client();
                        $googleClient->setClientId('DELETED');
                        $googleClient->setClientSecret('DELETED');
                        
                        if(explode('.', $_SERVER['HTTP_HOST'])[0] == 'dev') {
                            $googleClient->setRedirectUri('DELETED');
                        } else {
                            $googleClient->setRedirectUri('DELETED');
                        }
                        $googleClient->setAccessType('offline');
                        $googleClient->addScope('email');
                        $googleClient->addScope('profile');
                        $googleClient->addScope(Google_Service_Gmail::GMAIL_READONLY);

                        $googleClient->setAccessToken($office->office_google_token);
                        if(!empty($office->office_google_refresh_token))
                        {
                            $googleClient->refreshToken($office->office_google_refresh_token);
                            echo 'not empety refresh';
                        }
                        else
                        {
                            $googleClient->setAccessToken($office->office_google_token);
                        }

                        if($googleClient->isAccessTokenExpired() == TRUE)
                        {
                            // TOKEN IS EXPIRED
                            $this->debug(1, 'cronGmail/1', 'token for oauth: '.$office->office_google_login_oauth_id.' is expired');
                            $this->google_conn_model->setTokenExpiredForOffice($office->office_id);

                            $this->cronReport('cronGmail/1', $startTime, date('Y-m-d H:i:s', time()), 'token expired, oauth: '.$office->office_google_login_oauth_id, 0);
                        }
                        else
                        {
                            // TOKEN NOT EXPIRED
                            $gmailService = new Google_Service_Gmail($googleClient);

                            $connectParams                  = [];
                            $connectParams['maxResults']    = 100;

                            $getMessagesResult = $gmailService->users_messages->listUsersMessages('me', $connectParams);

工作一周后刷新令牌过期

这应该会导致 invalid_token 错误。

处于测试模式的应用程序会在 7 天后撤销其刷新令牌。

您需要将您的应用程序设置为生产状态才能获得持续时间更长的访问令牌。

由于您使用的是 gmail api 如果用户更改了密码,它也会过期。

重新登录后无法使用

实际上您的问题不在于授权登录。我不确定你从哪里得到这个

$office->office_google_refresh_token

但请确保当用户再次授权您的应用程序时,您存储了新的刷新令牌并且没有使用旧的。旧的刷新令牌已过期,无法再次使用。

或者,您可以让用户转到他们的 google 帐户并检查第三方访问权限,以确保您的应用程序的访问权限已被完全撤销。这将强制再次显示同意屏幕,然后用户可以再次授予您的应用程序访问权限。