如何在服务器上获取用户的日历信息?

Posted

技术标签:

【中文标题】如何在服务器上获取用户的日历信息?【英文标题】:How can I reach users' calendar information on server? 【发布时间】:2016-08-15 18:20:22 【问题描述】:

用户在我的 android 应用程序中授权。我正在将用户的令牌和其他信息发送到我的服务器。在这台服务器上,我想为用户实现一些逻辑。

我想要准确的this flow。

我按照 quickstart.php in this link 的步骤在服务器上获取用户的日历。

但我收到以下错误:

带有消息的 google oauth 异常 'could not json decode the token'

出于这个原因,我尝试了this solution。 但我也犯了同样的错误。因此,作为第三个选项,我自己创建了 json 格式,如下所示this solution。

$access_token = '
    "access_token":'.$access_token.',
    "token_type":"Bearer",
    "expires_in":3600, 
    "id_token":'.$id_token.', 
    "refresh_token":" ",
    "created":'. time() .'
';

如您所见,我不知道如何交换刷新令牌。我搜索了如何获取刷新令牌并看到了this question。并在我的代码中实现了this solution,但没有任何改变。

编辑 4:我尝试在 android 应用程序中获取访问令牌 according to this answer 并将其发送到应用程序服务器。我像以前一样使用代码:

GoogleSignInAccount acct = result.getSignInAccount();
code = acct.getServerAuthCode();//sending this code to AsyncTask to get access token

获取访问令牌的函数:

private void getAccessToken()throws GoogleAuthException, IOException
    new AsyncTask<Void, Void, String>() 
        @Override
        protected String doInBackground(Void... params) 
            List<String> scopes = new LinkedList<String>();
                scopes.add("https://www.googleapis.com/auth/calendar");
                scopes.add("https://www.googleapis.com/auth/calendar.readonly");
                scopes.add("https://www.googleapis.com/auth/urlshortener");

                GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(transport, jsonFactory, client_id, client_secret, scopes).build();

                try
                    GoogleTokenResponse res = flow.newTokenRequest(code).execute();
                    accessToken = res.getAccessToken();
                catch(IOException e)
                

在 php 服务器端,我更改了 user-example.php 文件,如下所示,因为我现在拥有访问令牌:

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setAccessType("offline");
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/urlshortener");
$service = new Google_Service_Urlshortener($client);
if (isset($_REQUEST['logout'])) 
    unset($_SESSION['access_token']);

$client->setAccessToken('"access_token":"'. $access_token .'","token_type":"Bearer","expires_in":3600,"created":'. time() .'');
if ($client->getAccessToken() && isset($_GET['url'])) 
$url = new Google_Service_Urlshortener_Url();
$url->longUrl = $_GET['url'];
$short = $service->url->insert($url);
$_SESSION['access_token'] = $client->getAccessToken();

但现在我遇到以下错误:

致命错误:C:\wamp\www\google-php\src\Google\Http\REST.php 中的未捕获异常 'Google_Service_Exception' 和消息 'Error calling POST https://www.googleapis.com/urlshortener/v1/url: (403) Insufficient Permission' 在线110

【问题讨论】:

单引号中的变量不会被评估。打开变量的字符串。 $sp = 'hi i am '.$name.' and i write strings.'; 我仍然有同样的 json 解码错误。 :\ 如果这两个标记不是整数,请将它们放在双引号中。 它们都是字符串。 This answer 改变主意不使用服务帐户 :( 我没有谷歌域,我不想冒充只有一个域的用户。我想我在谷歌的文件。:) 【参考方案1】:

在我开始使用 GoogleAuthorizationCodeFlow 获取访问令牌后,我收到了权限不足错误,正如我在 OP 中提到的那样。然后我尝试将日历范围添加到GoogleApiClient.Builder(this),但如果我添加Auth.GOOGLE_SIGN_IN_API,我将无法添加范围,因为我已将Auth.GOOGLE_SIGN_IN_API 添加到GoogleApiClient.Builder。所以这次我尝试将范围添加到 GoogleSignInOptions.Builder 并且它现在正在工作。我能够同时获得刷新令牌和访问令牌。下面的代码解决了我的问题:

GoogleSignInOptions gso = state.getGso();
if(gso == null)
    gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(new Scope("https://www.googleapis.com/auth/calendar"))
        .requestIdToken(getString(R.string.server_client_id))
        .requestEmail()
        .requestServerAuthCode(getString(R.string.server_client_id), false)
        .requestProfile()
        .build();

【讨论】:

嗨!你能帮我退出谷歌吗?如果您使用 googleAuth,我认为您必须在您的应用程序中实现它......我有这样的问题,我在第一个活动中实现了登录,但是我在另一个活动中实现了 LogOut 按钮,然后如果我点击这个按钮,我会调用 Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient)并得到错误GoogleApiClient is not connected yet. 据我了解我得到它是因为当我登录和注销时它是不同的实体......但是我如何保存同一个实体?你在你的应用程序中以哪种方式实现它? 我无法测试该项目,因为我现在没有服务器。据我从代码中了解:D,我记得使用不同标志的登录活动和 onConnected 函数的登录活动,我正在检查这个标志。如果标志为真,我只需通过设置结果回调来调用Auth.GoogleSignInApi.signOut 函数。但我很确定这不是实现这一目标的好方法。还有一些方法可以将值存储为全局值。可以查看this link,得到mGoogleApiClient对象后,可以查看是否连接。 据我记得onConnected() 方法是在以前的版本谷歌身份验证中提供的......在最后的实现中它有些不同......我的实现中没有这个方法(但我了解你的观点

以上是关于如何在服务器上获取用户的日历信息?的主要内容,如果未能解决你的问题,请参考以下文章

在服务器事件上向客户端发送信息

获取其他用户的Outlook可用性信息

如何从客户端套接字获取信息并在服务器上显示信息?

如何在日历服务器、Google 应用程序和 Exchange 中提供空闲/忙碌信息?

如何从日历数据库中获取可用时间段列表

彻底理解推送