如何验证Google身份验证访问令牌?
我需要以某种方式查询Google并询问:[给定访问令牌]是否对[example@example.com] Google帐户有效?
简短版本:
很清楚如何使用通过Google身份验证Api :: OAuth身份验证的Web应用程序提供的访问令牌,然后从一系列Google服务中请求数据.目前尚不清楚如何检查给定的访问令牌是否对给定的Google帐户有效.我想知道怎么做.
长版:
我正在开发一个使用基于令牌的身份验证的API.在提供有效的用户名+密码或从N个可验证服务中的任何一个提供第三方令牌时,将返回令牌.
其中一项第三方服务是Google,允许用户使用其Google帐户对我的服务进行身份验证.稍后将扩展到包括雅虎帐户,可信赖的OpenID提供商等.
基于Google的访问的示意图:
alt text http://webignition.net/images/figures/auth_figure002.png
"API"实体完全由我完全控制."公共接口"实体是任何基于Web或桌面的应用程序.一些公共界面在我的控制之下,其他公共界面不在我手中,而其他公共界面我甚至都不知道.
因此,我无法信任在步骤3中提供给API的令牌.这将与相应的Google帐户电子邮件地址一起提供.
我需要以某种方式查询Google并询问:此访问令牌是否对example@example.com有效?
在这种情况下,example @ example.com是Google帐户的唯一标识符 - 用户登录其Google帐户时使用的电子邮件地址.这不能被视为Gmail地址 - 有人可以拥有一个没有Gmail帐户的Google帐户.
Google文档明确说明了如何通过访问令牌从多个Google服务中检索数据.似乎没有任何东西可以说明如何在一开始就检查给定的访问令牌是否有效.
更新 令牌对N个Google服务有效.我不能尝试使用Google服务的令牌作为验证它的方法,因为我不知道给定用户实际使用的所有Google服务的哪个子集.
此外,我永远不会使用Google身份验证访问令牌来访问任何Google服务,仅仅是为了验证所谓的Google用户实际上是他们所说的人.如果还有另一种方法,我很乐意尝试.
对于用户检查,只需将访问令牌作为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的给定权限.您可以在此链接中查看范围ID
您可以使用此终结点验证Google身份验证访问令牌:
https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=
这是谷歌V3 OAuth AccessToken验证端点,你可以参考下面的谷歌文件:(在OAUTH 2.0 ENDPOINTS
标签中)
https://developers.google.com/identity/protocols/OAuth2UserAgent#validate-access-token
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; } }
好的,大多数答案都是有效的,但不太正确。JWT的想法是您可以验证令牌,而无需每次都与发行者联系。您必须检查ID,并使用用于签名令牌的Google证书的已知公钥验证令牌的签名。
请参阅下一篇文章为什么以及如何执行此操作。
http://ncona.com/2015/02/consumption-a-google-id-token-from-a-server/
Google oauth代码流响应以及access_token
返回的结果id_token
也包含有用的加密形式的验证信息。
使ID令牌有用的一件事是您可以在应用程序的不同组件之间传递它们。这些组件可以将ID令牌用作轻量级身份验证机制,对应用程序和用户进行身份验证。但是,在使用ID令牌中的信息或将其用作用户已通过身份验证的断言之前,必须先对其进行验证。
验证ID令牌需要几个步骤:
验证ID令牌是JWT,并已使用适当的Google公钥正确签名。
验证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。