谷歌登录oauth2每次都会重新询问访问权限


google login oauth2 re-ask access every time

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

我不需要离线访问,因为除了签入用户之外,我不使用任何API调用。不管怎样,我被困了,需要一些帮助!

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

我的代码:

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");我还不知道这是我唯一需要做的事情,还是我在浏览器/OS之间有一个错误:上次我在lion/chrome上试了一下,但没用,但在w7/firefox上还可以。好吧,这或者我只是失去了理智:p

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

有人指出你可以这样做:

$client->setApprovalPrompt('auto');

我遇到了一个类似的问题,似乎已经解决了消除$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);
    }
}

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

GoogleDriveSDK文档包括一个示例PHP应用程序,它实现了该流,您可以将其用作参考:

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

我认为您的问题是您没有在用户计算机上存储任何cookie。会话仅存储用户在网站上的持续时间内的信息。

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

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

设置脱机访问。为每个进行身份验证的用户存储初始令牌和刷新令牌,然后无论用户从哪里登录到您的应用程序,他们都将始终连接到他们的谷歌帐户,即使他们没有直接登录到谷歌本身,他们也将通过您的应用程序登录到谷歌。

与上述内容一样,这也包含在文档中。

如果用户永远不能这样做,那么拥有API将是毫无意义的。此外,它与cookie和会话无关。将服务器IP添加到谷歌开发者控制台,你就可以了。