首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将GoogleAuthUtil.getToken提供的访问令牌发送到php web服务器后进行身份验证

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

Stack Overflow用户
提问于 2014-11-29 08:24:33
回答 2查看 1.4K关注 0票数 1

我正在下面的链接中跟踪这些文档:

app

具体来说,这部分说:

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

我检索访问令牌如下:

代码语言:javascript
运行
复制
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服务器上,我可以通过调用

代码语言:javascript
运行
复制
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token']

上面的请求返回android应用程序客户端id,它也正确地返回用户电子邮件。

问题是,当我尝试运行$client->authenticate($_POST'google_access_token');时,我会得到一个异常:"invalid_grant:不正确的令牌类型“。

为了防止getToken缓存,我总是在android中使令牌失效:

if (accessToken != null && !accessToken.isEmpty()) {accessToken accessToken);}

下面是php代码:

代码语言:javascript
运行
复制
        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();行.问题是我不能得到given_name / family_name等等。只有电子邮件/ google_user_id从令牌信息..。

对于为什么密钥对tokeninfo有效,而不用于身份验证,有什么想法吗?

我试过许多不同的范围。服务器端和android端。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-01 15:56:01

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

代码语言:javascript
运行
复制
// 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();

注意:--如果你是在生产中的话,“模仿”expires_in并创建它可能是不明智的。你应该先打电话给tokeninfo,然后从那里得到过期的时间.

注意:我仍然不知道如何获得这个刷新令牌.但我不需要用用例。

票数 0
EN

Stack Overflow用户

发布于 2014-11-29 14:05:31

$client->authenticate()方法并不完全完成您想要做的事情。它从早期的OAuth事务中获取一次代码,并将其交换为访问令牌。在你的情况下-你是说你已经有了访问令牌。

您应该能够调用$client->setAccessToken()来设置令牌,因此它可能如下所示

代码语言:javascript
运行
复制
$client->setAccessToken($_POST['google_access_token']);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27200360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档