Google HTTP/REST OAuth:授权代码请求具有数据库用户的状态,访问令牌请求具有 none

Google HTTP/REST OAuth: authorisation code request has state for db user, access token request has none

我正在为 Google 使用 OAuth 服务器流程。 它从用户单击运行 javascript 的 link 开始,以在 URI 中打开一个弹出窗口,其中包含以下请求,一切正常:

var endpoint = "https://accounts.google.com/o/oauth2/auth";
        endpoint = endpoint + "?scope="+encodeURIComponent(googlecalendar.SCOPES);
        endpoint = endpoint + "&redirect_uri="+encodeURIComponent("https://myserver/google/");
        endpoint = endpoint + "&response_type=code";
        endpoint = endpoint + "&access_type=offline";
        endpoint = endpoint + "&approval_prompt=force";
        endpoint = endpoint + "&client_id="+encodeURIComponent(googlecalendar.CLIENT_ID);
        endpoint = endpoint + "&state="+encodeURIComponent(googlecalendar.USER_ID);

在服务器端,我获得了包含我的数据库的 user_id 和授权代码的状态。 现在我想交换访问令牌(和更新令牌)的授权码。这将是一个带有重定向 URI 的 HTTP 请求,不包含状态参数。

问题是,当我得到这些时,我需要将它们存储在我的数据库中,但我没有任何方法来检查回调是针对哪个用户的。

我能想到的最好办法是使用令牌查询它所属的 google 用户的身份,但这仍然无法帮助我在数据库中找到用户。

谁能帮我解决这个问题?一定有什么办法。我不想使用客户端库,因为稍后当我需要创建观察者时,PHP 客户端库不包括日历 API.

简答

尽管存在重定向参数,但访问令牌将生成标准的 200 响应,而不是 301 重定向。根据您发出和处理 request/response 的方式,您可以保留您的状态。

更详细的回答

根据 OAuth 2.0 规范文档 (RFC 6749) 的 section 4.1.4,对访问令牌请求的响应应该是“HTTP/1.1 200 OK”。

换句话说,服务器不会执行重定向,这意味着您可以在同一范围内发出请求并处理响应(无论您是在客户端还是在服务器中,无论您的情况如何),因此您的数据库用户 ID 需要仅在本地内存中。

这与授权请求不同,授权请求应该导致“HTTP/1.1 302 Found”(重定向)。参见 section 4.1.2

那么为什么需要 redirect_uri 参数?

根据section 4.1.3,服务器必须:

  • 确保“redirect_uri”参数存在,如果“redirect_uri”参数包含在第 4.1.1 节所述的初始授权请求中,并且如果确保它们的值相同。

换句话说,redirect_uri 充当服务器必须用来验证访问令牌请求的一种秘密或密码。如果客户端未能提供 redirect_uri 参数,或者参数值与原始请求不同,则服务器必须拒绝访问令牌请求。