【问题标题】:Ask authorization to use only first time to use calendar请求授权仅使用第一次使用日历
【发布时间】:2017-03-31 05:34:40
【问题描述】:

我只想要求用户访问该帐户一次。我有令牌,但 3600 秒后令牌过期。

这是我在框架“内部”的代码(工作)。谁能告诉我该怎么做?

public function actionEvent() {
    $client = new Google_Client();
    $client->setApplicationName("Google Calendar Event");
    $client->setAuthConfig(Yii::getAlias('@webroot') . '/calendar/client_secret.json');
    $client->addScope(\Google_Service_Calendar::CALENDAR);
    $client->setAccessType('offline');
    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
        $client->setAccessToken($_SESSION['access_token']);
        $calendar_service = new \Google_Service_Calendar($client);
        $event = new Google_Service_Calendar_Event(array(
                ..events here..
        ));
        $calendarId = 'primary';
        $event = $calendar_service->events->insert($calendarId, $event);
        var_dump($event->htmlLink);
    } else {
        $redirect_uri = $this->redirect(['pop/callback']);
    }
}

public function actionCallback() {
    $client = new Google_Client();
    $client->setApplicationName("Google Calendar Event");
    $client->setAuthConfigFile(Yii::getAlias('@webroot') . '/calendar/client_secret.json');
    $client->setRedirectUri('http://localhost/pop/callback');
    $client->addScope(\Google_Service_Calendar::CALENDAR);
    if (!isset($_GET['code'])) {
        $auth_url = $client->createAuthUrl();
        $this->redirect($auth_url);
    } else {
        $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();
        $this->redirect(['pop/event']);
    }
}

在会话内部我有:

array (size=3)
  '__flash' => 
    array (size=0)
      empty
  '__id' => int 1
  'access_token' => 
    array (size=4)
      'access_token' => string 'ya29.Ci-sf-asdfsadfsdfsd' (length=71)
      'token_type' => string 'Bearer' (length=6)
      'expires_in' => int 3599
      'created' => int 1479326378

谢谢

【问题讨论】:

  • 与您今天早些时候提出的另一个问题基本相同? stackoverflow.com/questions/40625179/…
  • 是的,但现在有代码。
  • 你可以更新令牌
  • 但是怎么做呢?我需要将第一个令牌存储在某个地方?
  • 是的,您存储第一个令牌之后,您只需使用存储的令牌来获取新令牌。您可以无限地执行此操作(直到用户删除权限)

标签: php oauth-2.0 google-calendar-api google-api-php-client google-api-client


【解决方案1】:

您的应用程序第一次对用户进行身份验证时,您会在$_SESSION['access_token'] = $client->getAccessToken(); 中返回一个刷新令牌。那是您需要获取刷新令牌$refrshToken = $_SESSION['access_token']['refresh_token]; 的时候,这样您就可以在 3600 秒后使用它来刷新访问令牌。如果您的应用第一次通过身份验证时没有保存刷新令牌,那么您必须将批准提示设置为强制 $client->setApprovalPrompt('force');,或者您可以从连接的应用和站点中删除该应用@ 987654321@

您可以尝试像这样修改您的 actionCallback 函数

public function actionCallback() {

    $client = new Google_Client();
    $client->setApplicationName("Google Calendar Event");
    $client->setAuthConfigFile(Yii::getAlias('@webroot') . '/calendar/client_secret.json');
    $client->setRedirectUri('http://localhost/pop/callback');
    $client->addScope(\Google_Service_Calendar::CALENDAR);

    if (!isset($_GET['code'])) {

        $client->setApprovalPrompt('force');
        $auth_url = $client->createAuthUrl();
        $this->redirect($auth_url);

    } else {

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

        //Save refresh token to cookie
        setcookie("autorefresh", $_SESSION['access_token']['refresh_token], 2000000000); 

        $this->redirect(['pop/event']);

    }
}

然后尝试像这样修改您的 actionEvent 函数

public function actionEvent() {

    $client = new Google_Client();
    $client->setApplicationName("Google Calendar Event");
    $client->setAuthConfig(Yii::getAlias('@webroot') . '/calendar/client_secret.json');
    $client->setAccessType('offline');
    $client->addScope(\Google_Service_Calendar::CALENDAR);

    if (isset($_COOKIE['autorefresh'])){

        if (!isset($_SESSION['access_token'])) {
            $_SESSION['access_token'] = $client->getAccessToken();
        }

        if( time() - $_SESSION['access_token']['created'] >= 3600){

            $refreshtoken = $_COOKIE['autorefresh'];           

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

        $calendar_service = new \Google_Service_Calendar($client);
        $event = new Google_Service_Calendar_Event(array(
            ..events here..
        ));
        $calendarId = 'primary';
        $event = $calendar_service->events->insert($calendarId, $event);
        var_dump($event->htmlLink);
    } else {
        actionCallback();
    }
}

请记住,不建议将刷新令牌保存到 Cookie 中!这只是为了测试刷新令牌系统的工作方式。我强烈建议您将其保存到文件或 sql 数据库中。我希望这会有所帮助!

【讨论】:

  • 谢谢 Morfinismo。我用另一种方式解决了我的问题。我正在将数据保存在数据库中。我需要清理所有会话变量才能获得 refresh_token。 (未设置($_SESSSION);)。
  • 我还有一个问题。每次我想从不同的设备访问 webapp 时,我需要接受吗? (使用相同的登录帐户和相同的gmail帐户,仅更改设备/浏览器)
  • 如果您将访问信息保存在数据库中,则不应发生这种情况。只有在您没有请求刷新令牌的访问代码时才会提示您接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
  • 2021-12-04
  • 2015-03-15
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多