如何验证 Google 身份验证 API 访问令牌?

如何验证 Google 认证访问令牌?

我需要以某种方式查询谷歌并问: [给定的访问令牌]对[ example@example.com ]谷歌帐户有效吗?

长话短说

很明显,通过 GoogleAuthenticationApi: : OAuth Web 应用程序身份验证提供的访问令牌可以用来从一系列 Google 服务请求数据。目前还不清楚如何检查给定的访问令牌是否对给定的谷歌帐户有效。我想知道是怎么回事。

说来话长

我正在开发一个使用基于令牌的认证的 API。如果提供了有效的用户名 + 密码,或者提供了来自任何一个 N可验证服务的第三方令牌,则将返回令牌。

第三方服务之一将是谷歌,允许用户使用他们的谷歌帐户对我的服务进行身份验证。这将在以后扩展到包括雅虎帐户、可信的 OpenID 提供商等等。

基于 Google 的访问示例:

alt text

“ API”实体在我的完全控制之下。“公共界面”实体是任何基于网络或桌面的应用程序。有些公共接口在我的控制之下,有些不在,还有些我可能永远都不会知道。

因此,我不能信任步骤3中提供给 API 的令牌。这将与相应的谷歌帐户电子邮件地址一起提供。

我需要以某种方式查询谷歌和问: 这个访问令牌对 example@example.com 有效吗

在这种情况下,example@example.com 是谷歌帐户唯一标识符——用户登录谷歌帐户时使用的电子邮件地址。这不能被认为是一个 Gmail 地址-有人可以有一个谷歌帐户没有 Gmail 帐户。

Google 文档清楚地说明了如何使用访问令牌从许多 Google 服务中检索数据。似乎没有说明如何首先检查给定的访问令牌是否有效。

更新 令牌对 N 个 Google 服务有效。我不能用令牌来验证 Google 服务,因为我不知道给定用户实际使用的 Google 服务的哪个子集。

此外,我将永远不会使用谷歌认证访问令牌来访问任何谷歌服务,仅仅作为一种手段来验证假定的谷歌用户实际上是谁,他们说他们是谁。如果还有别的方法,我很乐意尝试。

170104 次浏览

我需要以某种方式查询 Google 并问: 这个访问令牌对 example@example.com 有效吗?

没有。所有您需要的是请求标准登录与 谷歌帐户用户联合登录从您的 API 域。只有在那之后,你才能比较“持久用户 ID”和你从“公共接口”得到的 ID。

在 GoogleFederatedLogin 页面上使用 domain 的值来向用户标识请求站点。它还用于确定 Google 返回的持久用户 ID 的值。

所以你需要和“公共接口”来自同一个域。

不要忘记用户需要确保你的 API 是可信的;)所以 Google 会询问用户是否允许你检查他的身份。

尝试使用您的令牌向 https://www.google.com/accounts/AuthSubTokenInfo发出 OAuth 身份验证请求。这只有在 AuthSub 中才能使用,但是在 OAuth 中也可以使用。它不会告诉您这个令牌用于哪个用户,但是它会告诉您这个令牌对哪个服务有效,如果令牌无效或者已经被撤销,请求将失败。

任意的 OAuth 访问令牌不能用于身份验证,因为令牌的含义超出了 OAuth 核心规范。它可以用于单一用途或狭窄的过期窗口,也可以提供用户不想提供的访问。它也是不透明的,获得它的 OAuth 消费者可能从未见过任何类型的用户标识符。

一个 OAuth 服务提供商和一个或多个消费者可以很容易地使用 OAuth 来提供可验证的认证令牌,有一些建议和想法可以做到这一点,但是如果一个任意的服务提供商只使用 OAuth Core,那么如果没有与消费者的其他协调,就不能提供这种服务。特定于 Google 的 AuthSubTokenInfo REST 方法和用户标识符很接近,但是它也不适合,因为它可能使令牌无效,或者令牌可能过期。

如果你的 Google ID 是一个 OpenId 标识符,而你的“公共界面”是一个网络应用程序或者可以调用用户的浏览器,那么你可能应该使用 Google 的 OpenID OP。

OpenID 包括将用户发送到 OP 并获得一个已签名的断言。这种交互仅仅是为了 RP 的利益。没有长期存在的令牌或其他特定于用户的句柄可以用来表明 RP 已经成功地通过 OP 对用户进行了身份验证。

根据 OpenID 标识符验证以前的身份验证的一种方法是再次执行身份验证,假设使用的是相同的用户代理。OP 应该能够在没有用户交互的情况下返回正断言(例如,通过验证 cookie 或客户端证书)。OP 可以自由地需要另一个用户交互,如果身份验证请求来自另一个域,则可能需要(我的 OP 为我提供了重新验证这个特定 RP 的选项,而不需要在将来进行交互)。在 Google 的例子中,用户获取 OAuth 令牌的 UI 可能不使用相同的会话标识符,因此用户必须重新进行身份验证。但无论如何,你都可以确认身份。

function authenticate_google_OAuthtoken($user_id)
{
$access_token   = google_get_user_token($user_id); // get existing token from DB
$redirecturl    = $Google_Permissions->redirecturl;
$client_id      = $Google_Permissions->client_id;
$client_secret  = $Google_Permissions->client_secret;
$redirect_uri   = $Google_Permissions->redirect_uri;
$max_results    = $Google_Permissions->max_results;


$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$access_token;
$response_contacts  =  curl_get_responce_contents($url);
$response   =   (json_decode($response_contacts));


if(isset($response->issued_to))
{
return true;
}
else if(isset($response->error))
{
return false;
}
}

用户检查,只需发布 将访问令牌作为 access 令牌发布并获取响应

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=accessToken

你也可以在浏览器中尝试地址栏,也可以使用 httpppost 和 java 响应

反应就像

{
"issued_to": "xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
"audience": "xxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
"user_id": "xxxxxxxxxxxxxxxxxxxxxxx",
"scope": "https://www.googleapis.com/auth/userinfo.profile https://gdata.youtube.com",
"expires_in": 3340,
"access_type": "offline"
}

范围是 accToken 的给定权限。您可以检查 这个链接中的范围 id

更新: 新的空气污染指数 如下所示

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

我们的回应是

 {
// These six fields are included in all Google ID Tokens.
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"iat": "1433978353",
"exp": "1433981953",


// These seven fields are only included when the user has granted the "profile" and
// "email" OAuth scopes to the application.
"email": "testuser@gmail.com",
"email_verified": "true",
"name" : "Test User",
"picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
"given_name": "Test",
"family_name": "User",
"locale": "en"
}

了解更多信息,请登录 https://developers.google.com/identity/sign-in/android/backend-auth

下面是一个使用 狂饮的例子:

/**
* @param string $accessToken JSON-encoded access token as returned by \Google_Client->getAccessToken() or raw access token
* @return array|false False if token is invalid or array in the form
*
* array (
*   'issued_to' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
*   'audience' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
*   'scope' => 'https://www.googleapis.com/auth/calendar',
*   'expires_in' => 3350,
*   'access_type' => 'offline',
* )
*/
public static function tokenInfo($accessToken) {
if(!strlen($accessToken)) {
return false;
}


if($accessToken[0] === '{') {
$accessToken = json_decode($accessToken)->access_token;
}


$guzzle = new \GuzzleHttp\Client();


try {
$resp = $guzzle->get('https://www.googleapis.com/oauth2/v1/tokeninfo', [
'query' => ['access_token' => $accessToken],
]);
} catch(ClientException $ex) {
return false;
}


return $resp->json();
}

Google oauth 代码流响应 除了 access_token之外,还返回包含有用于加密形式的验证信息的 id_token

使 ID 标记有用的一个事实是您可以传递 你的应用程序的不同组件。这些组件可以使用 作为轻量级身份验证机制的 ID 令牌 应用程序和用户。但在您可以使用 ID 中的信息 令牌或依赖它作为用户已验证的断言, 你必须验证它。

验证 ID 令牌需要几个步骤:

  • 验证 ID 令牌是否是一个使用适当的 Google 公钥正确签名的 JWT。
  • 验证 ID 令牌中的 aud 值是否等于应用程序的客户端 ID。
  • 验证 ID 标记中的 iss 值是否等于 accounts.google.com 或 https://accounts.google.com
  • 验证 ID 令牌的到期时间(exp)是否已过。
  • 如果在请求中传递了一个 hd 参数,请验证 ID 令牌的 hd 声明是否与您的 GoogleApps 托管域相匹配。

Https://developers.google.com/identity/protocols/openidconnect#validatinganidtoken 链接有验证 ID 令牌的代码样本。

参见 https://security.stackexchange.com/questions/37818/why-use-openid-connect-instead-of-plain-oauth

好吧,大多数答案是有效的,但不完全正确。JWT 的思想是您可以验证令牌,而无需每次都与发行者联系。您必须检查 id,并使用 google 用于签署令牌的证书的已知公钥来验证令牌的签名。

请参阅下一篇文章,了解为什么要这样做以及如何这样做。

Http://ncona.com/2015/02/consuming-a-google-id-token-from-a-server/

您可以使用以下端点验证 Google 身份验证访问令牌:

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access_token>

这是 Google V3 OAuth AccessToken 验证端点,您可以从以下 Google 文档中参考: (在 OAUTH 2.0 ENDPOINTS Tab 中)

Https://developers.google.com/identity/protocols/oauth2useragent#validate-access-token

  1. 根据 Google 的 文件,您应该使用 Google 的 AP 客户端库,这样做(令牌验证、索赔提取等)比编写自己的自定义代码容易得多。

  2. 从性能角度来看,应该在本地解析令牌,而不需要再次调用 Google。当然,Google 的公共密钥是必需的,而且对这个密钥的检索是通过一个缓存策略完成的,这个策略在 Google 的客户端库中从上面第一条开始实现。

  3. 仅供参考。谷歌也使用 JWT 令牌。参见下面的图片作为参考。

enter image description here

使用以下端点获取用户信息,如姓名、电子邮件、照片等。

https://www.googleapis.com/oauth2/v3/userinfo?access_token=<access token>

使用下面的端点获取令牌信息,比如到期时间、令牌范围等。

https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=<access token>

检查下面的网址。它工作得很好。它的官方文件从谷歌自己。

使用 Google API 客户端库(例如 Java、 Node.js、 PHP、 Python)是验证 Google ID 令牌的推荐方法。

Https://developers.google.com/identity/sign-in/android/backend-auth#using-a-google-api-client-library