Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将GoogleAuthUtil.getToken提供的访问令牌发送到php web服务器后,对其进行身份验证_Php_Android_Google Plus_Google Oauth_Google Api Php Client - Fatal编程技术网

将GoogleAuthUtil.getToken提供的访问令牌发送到php web服务器后,对其进行身份验证

将GoogleAuthUtil.getToken提供的访问令牌发送到php web服务器后,对其进行身份验证,php,android,google-plus,google-oauth,google-api-php-client,Php,Android,Google Plus,Google Oauth,Google Api Php Client,我正在以下链接中查看文档: 特别是说: 如果不需要脱机访问,可以检索访问令牌并通过安全连接将其发送到服务器。您可以直接使用GoogleAuthUtil.getToken()获取访问令牌,方法是在不使用服务器OAuth 2.0客户端ID的情况下指定作用域。例如: 我检索访问令牌,如下所示: accessToken = GoogleAuthUtil.getToken( AuthenticatorActivity.this,

我正在以下链接中查看文档:

特别是说:

如果不需要脱机访问,可以检索访问令牌并通过安全连接将其发送到服务器。您可以直接使用GoogleAuthUtil.getToken()获取访问令牌,方法是在不使用服务器OAuth 2.0客户端ID的情况下指定作用域。例如:

我检索访问令牌,如下所示:

accessToken = GoogleAuthUtil.getToken(
                        AuthenticatorActivity.this,
                        Plus.AccountApi.getAccountName(Common.mGoogleApiClient),
                        "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.login email"
                );
检索访问令牌后,我将其发送到web服务器,在web服务器上,通过调用

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token']
上面的请求返回android应用程序客户端id,它还正确返回用户电子邮件

问题是,当我尝试运行$client->authenticate($\u POST['google\u access\u token');我收到一条异常消息:“无效的授权:不正确的令牌类型”

为了防止getToken缓存,我总是在android应用程序中使令牌无效:

if(accessToken!=null&&!accessToken.isEmpty()){ GoogleAuthUtil.invalidateToken(AuthenticatorActivity.this,accessToken); }

以下是php代码:

        if (!isset($_POST['google_access_token'])) {
        throw new Exception('missing google_access_token');
    }


    $client = new \Google_Client();
    $client->setApplicationName("GiverHub");

    $client->setClientId($this->config->item('google_client_id'));
    $client->setClientSecret($this->config->item('google_client_secret'));

    $client->setDeveloperKey($this->config->item('google_developer_key'));
    $client->setRedirectUri($this->config->item('google_redirect_uri'));

    $client->setScopes([
        'https://www.googleapis.com/auth/plus.login',
        'https://www.googleapis.com/auth/plus.me',
        'email',
    ]);



    try {
        $client->authenticate($_POST['google_access_token']);  // if i remove this the rest of the code below works!  ...
        $reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token'];
        $req = new \Google_Http_Request($reqUrl);

        $io = $client->getIo();
        $response  = $io->executeRequest($req);


        $response = $response[0];

        $response = json_decode($response, true);
        if ($response === null) {
            throw new Exception('Failed to check token. response null');
        }

        if ($response['issued_to'] !== '466530377541-s7cfm34jpf818gbr0547pndpq9songkg.apps.googleusercontent.com') {
            throw new Exception('Invalid access token. issued to wrong client id: '. print_r($response, true));
        }

        if (!isset($response['user_id'])) {
            throw new Exception('Missing user_id');
        }

        if (!isset($response['email'])) {
            throw new Exception('Missing email');
        }

        /** @var \Entity\User $user */
        $user = Common::create_member_google([
            'id' => $response['user_id'],
            'email' => $response['email'],
            'given_name' => '',
            'family_name' => '',
        ]);
        $user->login($this->session);
        if ($user instanceof \Entity\User) {
            echo json_encode( [ 'success' => true, 'user' => $user ] );
        } else {
            echo json_encode( [ 'success' => false, 'msg' => $user ] );
        }
    } catch(Exception $e) {
        echo json_encode(['success' => false, 'msg' => $e->getMessage()]);
    }
如果我删除$client->authenticate(),上面的代码就可以工作;线问题是我无法获得给定的姓名/姓氏等。。仅来自tokeninfo的电子邮件/谷歌用户id

有没有想过为什么密钥适用于令牌信息而不适用于身份验证


我试过许多不同的示波器。。无论是在服务器端还是android端,
$client->authenticate()
方法都无法完成您想要完成的任务。它从早期的OAuth事务中获取一次性代码,并将其交换为访问令牌。在您的情况下,您是说您已经拥有访问令牌

您应该能够调用
$client->setAccessToken()
来设置令牌,因此它看起来像

$client->setAccessToken($_POST['google_access_token']);

这是我在user158443建议我使用$client->setAccessToken()后提出的解决方案

注意:如果您正在生产中,“模仿”我刚刚创建的expires\u可能并不明智。。。您可能应该首先调用tokeninfo并从那里获取过期时间


注意:我仍然不知道如何为此获取刷新令牌。。。但是我的用例不需要一个。

谢谢你的回复。。。我已经尝试了您的建议,使用$client->setAccessToken();好几次。它不起作用$client->setAccessToken()需要一个json格式的字符串。。它还需要一个访问令牌和一个刷新令牌。。我不知道如何将androids getToken()生成的访问令牌转换为$client->setAccessToken()可以接受的json字符串引发异常,并显示以下消息:无法对令牌进行json解码。我通过基于$_POST['google_access_token']创建json字符串,然后调用$client->setAccessToken()解决了此问题;
// first json_encode the access token before sending it to $client->setAccessToken();
$json_encoded_access_token = json_encode([
            'access_token' => $_POST['google_access_token'],
            'created' => time(),  // make up values for these.. otherwise the client thinks the token has expired..
            'expires_in' => time()+60 // made up a value in the future... 
        ]);

// and then set it
$client->setAccessToken($json_encoded_access_token);

// and then get userinfo or whatever you want from google api !! :)
$oauth2 = new \Google_Service_Oauth2($client);
$user_info = $oauth2->userinfo->get();