6

我正在尝试将 google oauth2 api 用于我的登录系统。它几乎可以工作了,用户可以访问我的 Web 应用程序,我阅读信息并连接用户。问题是,一旦他们离开或更换浏览器,回到我的网站,他们会再次被要求授予访问权限。

我不需要离线访问,因为除了签入用户之外,我没有使用任何 API 调用。无论如何,我被困住了,需要一些帮助!

我正在使用 google php 库(https://code.google.com/p/google-api-php-client/wiki/OAuth2),我什至将 ApprovalPrompt 设置为自动。仍然没有运气。

我的代码:

public function googleLogin()
{
    $this->set('connect', "Google login");
    $client = new apiClient();
    $client->setApprovalPrompt('auto');
    $client->setApplicationName("Authentication");
    $client->setClientId(G_OAUTH2_APP_ID);
    $client->setClientSecret(G_OAUTH2_SECRET);
    $client->setRedirectUri(G_REDIRECT_URI);
    $client->setDeveloperKey(G_DEV_KEY);
    $oauth2 = new apiOauth2Service($client);

    if (isset($_GET['code'])) {
        $client->authenticate();
        $_SESSION['token'] = $client->getAccessToken();
        $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
        header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));

    }

    if (isset($_SESSION['token'])) {
        $client->setAccessToken($_SESSION['token']);
    }

    if (isset($_REQUEST['logout'])) {
        unset($_SESSION['token']);
        $client->revokeToken();
    }
    //print_r($client->getAccessToken()); exit;

    if ($client->getAccessToken()) {
        $user = $oauth2->Guserinfo->get();


        // These fields are currently filtered through the PHP sanitize filters.
        // See http://www.php.net/manual/en/filter.filters.sanitize.php
        //$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
        //$img = filter_var($user['picture'], FILTER_VALIDATE_URL);

        // The access token may have been updated lazily.
        $_SESSION['token'] = $client->getAccessToken();

        //do stuff with user data
        $data = $this->linkUser($user, "google");
        if ($data['state']=="createUser") {
            $this->set("data",$data);
        }

    } else {
        $authUrl = $client->createAuthUrl();
        header("Location: " . $authUrl);
    }
}

编辑: 我添加了$client->setAccessType("online"); 我不知道的行,如果这是我唯一需要做的事情,或者如果我在浏览器/操作系统之间有错误:上次我尝试使用 lion/chrome 它没有工作但在 w7/firefox 上没关系。好吧,否则我只是失去理智:p

4

5 回答 5

11

关于这里的另一个问题:Google API - 每次都强制授予权限

有人指出你可以这样做:

$client->setApprovalPrompt('auto');

于 2013-01-08T10:14:44.263 回答
3

我有一个类似的问题,似乎解决了消除 $client->revokeToken(),在登录之前移动注销的东西。

我不知道避免使令牌无效是否是一个有效的想法,但它似乎有效。

试试这个:

public function googleLogin()
{
    $this->set('connect', "Google login");
    $client = new apiClient();
    $client->setApprovalPrompt('auto');
    $client->setApplicationName("Authentication");
    $client->setClientId(G_OAUTH2_APP_ID);
    $client->setClientSecret(G_OAUTH2_SECRET);
    $client->setRedirectUri(G_REDIRECT_URI);
    $client->setDeveloperKey(G_DEV_KEY);
    $oauth2 = new apiOauth2Service($client);

    // I moved the logout stuff here, without invalidating the token
    if (isset($_REQUEST['logout'])) {
        unset($_SESSION['token']);            
    }

    if (isset($_GET['code'])) {
        $client->authenticate();
        $_SESSION['token'] = $client->getAccessToken();
        $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
        header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));

    }

    if (isset($_SESSION['token'])) {
        $client->setAccessToken($_SESSION['token']);
    }

    /* // I solved getting this stuf commented
    if (isset($_REQUEST['logout'])) {
        unset($_SESSION['token']);
        $client->revokeToken();
    }*/
    //print_r($client->getAccessToken()); exit;

    if ($client->getAccessToken()) {
        $user = $oauth2->Guserinfo->get();


        // These fields are currently filtered through the PHP sanitize filters.
        // See http://www.php.net/manual/en/filter.filters.sanitize.php
        //$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
        //$img = filter_var($user['picture'], FILTER_VALIDATE_URL);

        // The access token may have been updated lazily.
        $_SESSION['token'] = $client->getAccessToken();

        //do stuff with user data
        $data = $this->linkUser($user, "google");
        if ($data['state']=="createUser") {
            $this->set("data",$data);
        }

    } else {
        $authUrl = $client->createAuthUrl();
        header("Location: " . $authUrl);
    }
}
于 2012-09-11T23:16:21.617 回答
0

您必须保存用户第一次在数据库中授予对您的应用程序的访问权限时获得的刷新令牌,并将其重用于未来的请求。

Google Drive SDK 文档包含一个实现该流程的示例 PHP 应用程序,您可以将其用作参考:

https://developers.google.com/drive/examples/php

于 2012-09-05T08:10:20.777 回答
0

设置离线访问。为每个经过身份验证的用户存储初始令牌和刷新令牌,然后无论用户从何处登录您的应用程序,他们都将始终连接到他们的 Google 帐户,即使他们没有直接登录到 Google,他们也会登录到 Google通过您的应用程序。

像上面一样,这在文档中有所介绍。

如果用户永远无法做到这一点,那么拥有 API 将毫无意义。此外,它与 cookie 和会话无关。将服务器 IP 添加到 Google 开发者控制台,就可以了。

于 2015-04-13T19:11:02.120 回答
0

我相信您的问题是您没有在用户计算机上存储任何 cookie。会话仅在用户访问网站期间存储信息。

这是关于 cookie 的一个很好的简单解释。希望能帮助到你。

http://www.tizag.com/phpT/phpcookies.php

于 2012-09-05T08:11:27.500 回答