使用 google api 时如何设置 refresh_token?

2022-01-01 00:00:00 google-api php google-api-php-client

我正在编写一个示例,试图了解如何使用 google api 更改日历上的事件.服务器是将根据数据库中的信息更新日历的用户.实际上不需要用户交互.

I'm working off an example trying to learn how to use the google api to change events on a calendar. The server is the user which will update the calendar based off of information in a database. No user interaction is actually required.

问题是我在获取/使用刷新令牌时遇到问题.我点击添加到页面的连接我"链接,它给了我一个错误:

The problem is I am having issues getting/using refresh tokens. I click the "Connect Me" link that gets added to the page and it gives me an error:

致命错误:未捕获的异常Google_Auth_Exception",消息为刷新 OAuth2 令牌时出错,消息:"{错误":invalid_request",error_description":缺少必需参数:refresh_token"}

我尝试以这种方式设置刷新令牌,以及类似的方法,但它们似乎都不起作用让我觉得我没有正确地实施它们.

I have tried setting the refresh token this way, along with similar methods, but none of them seem to work which makes me think I am implementing them incorrectly.

当我打印出 $_SESSION['access_token'] 变量时,它没有显示 refresh_token:

When I print out the $_SESSION['access_token'] variable, it shows no refresh_token:

{"access_token":"token","token_type":"Bearer","expires_in":3599,"created":1417534503}

这是我用来在没有 refresh_token 部分的情况下授权用户"的函数(基于示例):

Here is the function I am using to authorize the 'user' without the refresh_token portion(based off an example):

function googleAuth(){

    $client_id = 'myclientid';
    $client_secret = 'myclientsecret';
    $redirect_uri = 'redirecturi';
    $client = new Google_Client();
    $client->setAccessType('offline');
    $client->setClientId($client_id);
    $client->setClientSecret($client_secret);
    $client->setRedirectUri($redirect_uri);
    $client->setScopes('https://www.googleapis.com/auth/calendar');

    /************************************************
    If we're logging out we just need to clear our
    local access token in this case
    ************************************************/
    if (isset($_REQUEST['logout'])) {
    unset($_SESSION['access_token']);
    }
    /************************************************
    If we have a code back from the OAuth 2.0 flow,
    we need to exchange that with the authenticate()
    function. We store the resultant access token
    bundle in the session, and redirect to ourself.
    ************************************************/
    if (isset($_GET['code'])) {
        $resp = $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();

        $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
        header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));

    }
    /************************************************
    If we have an access token, we can make
    requests, else we generate an authentication URL.
    ************************************************/
    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
        $client->setAccessToken($_SESSION['access_token']);
    } else {
        $authUrl = $client->createAuthUrl();
    }

    if (isset($authUrl)) {
        echo "<a class='login' href='" . $authUrl . "'>Connect Me!</a>";
    }

    return $client;
}

这是我用来将事件添加到日历的代码:

Here is the code I am using to add the event to the calendar:

function addEvent($title, $location, $startTime, $stopTime, $client){

    $event = new Google_Service_Calendar_Event();
    $start = new Google_Service_Calendar_EventDateTime();

    $event->setSummary($title);
    $event->setLocation($location);

    $start->setDateTime($startTime);

    $end = new Google_Service_Calendar_EventDateTime();

    $end->setDateTime($stopTime);

    $event->setStart($start);
    $event->setEnd($end);

    $atendee = new Google_Service_Calendar_EventAttendee();
    $atendee->setEmail('someGuy@someDomain.com');

    $atendees = array($atendee);

    $event->attendees = $atendees;

    $service = new Google_Service_Calendar($client);

    $event_id = $service->events->insert('primary', $event);

}

如何设置缺少的参数:refresh_token"?代码结构有问题吗?我已经浏览了文档,我愿意多看一些,但如果有人能帮忙解释如何做到这一点,那就太棒了.谢谢!

How can I set the missing parameter: "refresh_token"? Are there issues with the structure of the code? I have looked through documentation, and I am willing to look some more, but if somebody can lend a hand at explaining how to do this, that would be amazing. Thanks!

推荐答案

检查token是否有refresh-token(如果你请求离线访问,refresh-token会在第一次和access token一起发送).

Check if the token has a refresh-token (if you request offline access, the refresh-token will be sent with the access token the first time).

类似的东西

 $token = $client->getAccessToken();
 $authObj = json_decode($token);
 if(isset($authObj->refresh_token)) {
     save_refresh_token($authObj->refresh_token);
 }

save_refresh_token 在哪里保存你的刷新令牌(db).

Where save_refresh_token saves your refresh-token somewhere (db).

然后您可以通过以下方式检查令牌是否已过期:

Then you can check if token as expired by:

 $client->isAccessTokenExpired()

如果是,你可以更新:

$client->refreshToken($your_saved_refresh_token);

然后将您的新访问令牌设置为会话:

And then set your new access token to the session:

 $_SESSION['access_token'] = $client->getAccessToken();

相关文章