1

我正在尝试构建一个基本应用程序,我可以在其中使用 Google 的 RESTful api 修改我自己的 google 日历,但我无法获取 oAuth 令牌。我选择使用服务应用程序 oAuth 流程来执行此操作 - 我不想不断地重新同意让我自己的应用程序使用我的日历,但如果有更好的方法可以做到这一点,请告诉我。

每次我发出 http 请求时,都会收到 Bad Request 错误。有什么想法/帮助吗?

这是代码:

            <?php

            $payload = array(
                   "iss"=>"services client email",
                   "scope"=>"https://www.googleapis.com/auth/calendar",
                   "aud"=>"https://accounts.google.com/o/oauth2/token",
                   "iat"=>date("U"),
                   "exp"=>date("U")+3600
                );

            $key = "Simple API key";
            $jwt = encode_header($payload,$key);

            print_r(request_g_token($jwt));


            function request_g_token($jwt)
            {
                $data = array(
                    'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                    'assertion' => $jwt
                );

                $data = http_build_query($data);
                $url = "https://accounts.google.com/o/oauth2/token";
                //echo $data;
                $opts = array('http' =>
                    array(
                        'protocol_version' => '1.1',    
                        'method'  => 'POST',
                        'header' => "Host: accounts.google.com\r\n" .
                                    "Content-Type: application/x-www-form-urlencoded\r\n",
                        'content' => $data
                    )
                );

                $context = stream_context_create($opts);

                return (file_get_contents($url, false, $context));
            }

            function urlsafeb64encode($input){
                return str_replace('=','',strtr(base64_encode($input),'+/','-_'));
            }

            function encode_header($payload, $key, $algo = 'RS256'){
                $header = array('typ' => 'JWT', 'alg' => $algo);

                $segments = array();
                $segments[] = urlsafeb64encode(json_encode($header));
                $segments[] = urlsafeb64encode(json_encode($payload));
                $signing_input = implode('.',$segments);

                $sig = sign_encode($signing_input,$key);
                $segments[]=urlsafeb64encode($sig);

                return implode('.',$segments);
            }

            function sign_encode($msg, $key){
                    return hash_hmac('sha256', $msg, $key, true);
            }
            ?>  

任何帮助将不胜感激

更新

所以我再次经历了服务过程,意识到我需要使用私钥,我现在正在这样做。我的主要问题是是否包含我从谷歌下载的“private-key.p12”部分。不幸的是,我仍然收到错误请求错误...

更新 2

意识到我需要pk12 文件中提取密钥,我使用以下代码进行了操作:

    function getKey($file){
        $p12cert = array();

        $fd = fopen($file, 'r');
        $p12buf = fread($fd,filesize($file));
        fclose($fd);

        if ( openssl_pkcs12_read($p12buf, $p12cert, 'notasecret') )
        {
            //worked
            $temp = $p12cert['pkey'];
            $temp = str_replace("-----BEGIN PRIVATE KEY-----","",$temp);
            $temp = str_replace("-----END PRIVATE KEY-----","",$temp);
            return $temp;
        }
        else
        {
            //failed
            return "failed";
        }   
    }

但是,它仍然给我一个错误的请求错误,我认为这与密钥以多行返回的事实有关。有任何想法吗?

4

1 回答 1

0

对于遇到此问题的任何人,我基本上得出的结论是,谷歌尚未将日历与他们的服务帐户进行交互,并且正在使用刷新令牌来实现类似的结果,而无需一直登录。

于 2013-07-16T03:10:21.607 回答