ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

精简版

很清楚如何使用通过 Google Authentication Api :: OAuth Authentication for Web Applications 提供的访问令牌然后从一系列 Google 服务请求数据。目前尚不清楚如何检查给定的访问令牌是否对给定的 Google 帐户有效。我想知道怎么做。

长版

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

其中一项第三方服务将是 Google,它允许用户使用他们的 Google 帐户对我的服务进行身份验证。稍后将扩展到包括 Yahoo 帐户、受信任的 OpenID 提供商等。

基于 Google 的访问的示意图示例:

https://webignition.net/images/figures/auth_figure002.png

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

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

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

在这种情况下,example@example.com 是 Google 帐户的唯一标识符 - 某人用于登录其 Google 帐户的电子邮件地址。这不能被假定为 Gmail 地址 - 有人可以拥有 Google 帐户而没有 Gmail 帐户。

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

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

此外,我永远不会使用 Google 身份验证访问令牌来访问任何 Google 服务,只是作为一种验证假定的 Google 用户实际上是他们所说的人的手段。如果有另一种方法可以做到这一点,我很乐意尝试。

这个问题是关于什么特定的身份验证服务(OAuth、AuthSub、已安装的应用程序,...)?请提供更详细的链接。
@Martin v. Löwis:“Web 应用程序的 OAuth 身份验证”服务 - 我已经更新了问题的开头以反映这一点。感谢您指出了这一点!
关于 google 密钥验证的有趣文章可能会提供更多见解groups.google.com/group/Google-Maps-API/msg/f9e3c5ad3cbda4d7
仅供参考:即使没有 https,图像 URL 也是 404。

V
Vinoj John Hosan

对于用户检查,只需发布获取访问令牌作为 accessToken 并发布它并获取响应

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

您也可以在浏览器的地址栏中尝试,也可以在 java 中使用 httppost 和 response

反应会像

{
     "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"
    }

范围是 accessToken 的给定权限。您可以在 this link 中检查范围 ID

更新:新的 API 帖子如下

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


谷歌的 oauth2 - v3 有一个更新的版本。请参阅此处的示例:developers.google.com/identity/sign-in/android/backend-auth
-1 “它不适合在生产代码中使用,因为请求可能会受到限制或以其他方式受到间歇性错误的影响。” developers.google.com/identity/sign-in/ios/… Remco 的答案是正确的
使用更新的 API,我可以检索用户的 google id 吗?
R
Remco

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

请参阅下一篇文章为什么以及如何做到这一点。

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


请多点赞! The idea of JWT is that you can validate the token without the need to contact the issuer everytime.
是的!如果他们只是打电话给谷歌以获取令牌信息,他们就是 ddos-ing 谷歌
您不能使用 Google 访问令牌执行此操作,因为它们不是 JWT。检查stackoverflow.com/questions/48623656/…
@DanielJaramillo 感谢您的洞察力。 id 部分实际上是一个可验证的 jwt。点仍然存在。离线验证是这里的主要思想。
谢谢!该文档指出“它不适合在生产代码中使用,因为请求可能会受到限制或以其他方式受到间歇性错误的影响。” developers.google.com/identity/sign-in/web/…
N
Nick Tsai

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

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

这是 Google V3 OAuth AccessToken 验证端点,您可以参考下面的 google 文档:(在 OAUTH 2.0 ENDPOINTS 选项卡中)

https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token


对于后端文档 - 文档来源是 here
a
ahmed
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;
    }
}

这个答案几乎仍然有效。 Issued_to 似乎不再设置。 developers.google.com/accounts/docs/…
C
Community

Google oauth code flow response 除了 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 令牌具有与您的 Google Apps 托管域匹配的 hd 声明。

https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken 链接包含用于验证 ID 令牌的代码示例。

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


S
Steev James

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

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

使用以下代码获取令牌信息,例如到期时间、令牌范围等。

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

V
Vikram Rawat

根据 Google 的文档,您应该使用 Google 的 AP 客户端库,这使得这(令牌验证、声明提取等)比编写自己的自定义代码更容易。从性能的角度来看,应该在本地解析令牌,而无需再次调用 Google。离场谷歌的公钥是必需的,并且该密钥的检索是使用缓存策略完成的,在上面#1的谷歌客户端库中实现。仅供参考。 Google 还使用 JWT 令牌。请参阅下图以供参考。

https://i.stack.imgur.com/18tuc.png


M
Malx

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

不需要。您只需要使用您的 API 域中的 Federated Login for Google Account Users 请求标准登录。只有在那之后,您才能将“持久用户 ID”与“公共界面”中的用户 ID 进行比较。

在 Google 联合登录页面上使用 realm 的值来向用户识别请求站点。它还用于确定 Google 返回的持久用户 ID 的值。

因此,您需要来自与“公共接口”相同的域。

并且不要忘记用户需要确保您的 API 是可信的;)因此 Google 会询问用户是否允许您检查他的身份。


m
mpen

以下是使用 Guzzle 的示例:

/**
 * @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();
}

J
Jonathan

尝试使用您的令牌向 https://www.google.com/accounts/AuthSubTokenInfo 发出经过 OAuth 身份验证的请求。这仅被记录为适用于 AuthSub,但它也适用于 OAuth。它不会告诉您令牌适用于哪个用户,但会告诉您它对哪些服务有效,并且如果令牌无效或已被撤销,请求将失败。


K
Karl Anderson

任意 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 可能不会使用相同的会话标识符,因此用户必须重新进行身份验证。但无论如何,您都可以断言身份。


OpenID 2.0 最近被 Google 弃用和禁用,转而支持提供 verifyable id tokens 的基于 OAuth 的 OpenID Connect。
N
Nikhil

检查以下网址。它运作良好。它的官方文件来自谷歌本身。

推荐使用 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