如何在 C# / .NET 中的服务器端验证 Google Identity Service (GIS) 访问令牌?

2024-02-22

我正在从旧的 Google 登录库迁移到新的 Google Identity Services (GIS) 库。这是强制性的,因为从 2023 年 3 月起旧的将不再使用。

之前,我做了(为了清晰起见,进行了简化):

<script src="https://apis.google.com/js/api:client.js"></script>
gapi.load();
var auth2 = gapi.auth2.init();
auth2.attachClickHandler();
onGoogleSignIn(googleUser); // attachClickHandler's callback
var profile      = googleUser.getBasicProfile(); // profile info accessible
var authResponse = googleUser.getAuthResponse(); // auth response accessible
var accessToken  = authResponse.id_token; // get actual access token

现在,我正在尝试(为了清楚起见,进行了简化):

<script src="https://accounts.google.com/gsi/client"></script>
var gisClient = google.accounts.oauth2.initTokenClient();
gisClient.requestAccessToken();
callback(); // initTokenClient's callback
var accessToken = response.access_token; // get access token in callback

使用旧的谷歌登录库,我验证了访问令牌服务器端,如下所示:

Payload payload = await GoogleJsonWebSignature.ValidateAsync(accessToken);

这还会在有效负载中返回用户的电子邮件和姓名。

我从 GIS 获取的访问令牌比从 GAPI 获取的旧访问令牌短得多。

An 在线令牌调试器 https://jwt.io/告诉我这不是有效的 JWT 令牌。

ValidateAsync 方法抛出异常:

JWT must consist of Header, Payload, and Signature

考虑到它不是有效的 JWT 令牌,这并不奇怪。

我还尝试了以下调用:

Payload payload = await JsonWebSignature.VerifySignedTokenAsync(AccessToken, options);

相同的结果。

The 官方文档 https://developers.google.com/identity/gsi/web/guides/verify-google-id-token没有说明如何为 C# / .NET 验证此令牌服务器端。

我在文档中的任何地方都找不到这方面的帮助。

我该怎么做才能与 Google Identity Services 一起进行服务器端访问令牌验证(以及电子邮件+个人资料的检索)?


解释

新的 Google 登录返回“凭证响应 https://developers.google.com/identity/gsi/web/reference/js-reference#CredentialResponse” 其中包含一个名为credential,这是您需要的 base64 格式的 JSON Web Token (JWT)。
该 JWT 可以发送到客户端或服务器进行验证。
验证后您将收到用户个人资料数据。

Client

<div id="g_id_onload"
     data-client_id="YOUR_GOOGLE_CLIENT_ID"
     data-callback="handleCredentialResponse">
</div>
<script>

    function handleCredentialResponse(response) {

        //get JSON Web Token (JWT) out of the response object
        var jwt = response.credential;

        //send JWT to backend server for validation
        var result = ValidateAtServer(jwt);

        //do something with result
        KillUserInstantly(result);
    }
</script>

服务器(.NET)

public static void ValidateAtServer(httpRequest)
{
  //get jwt string from request
  ...

  //validate it using Google.Apis.Auth (null if invalid)
  var validPayload = await GoogleJsonWebSignature.ValidateAsync(jwtToken);

  //get user data & use it
  var userId = validPayload.Subject; //The unique ID of the user's Google Account
  var email = validPayload.Email;

  //do something with data
  ...
}

初学者笔记

  1. “唯一用户 ID”位于subject or sub
  2. “ID 令牌”是 base64 编码的 JSON Web 令牌 (JWT) 字符串。
  3. 验证 JWT 还会解密其中包括用户配置文件的数据。

JWT/ID 令牌示例

eyJhbGciOiJSUzI1NiIsImtpZCI6IjE1NDllMGFlZjU3NGQxYzdiZGQxMzZjMjAyYjhkMjkwNTgwYjE2NWMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2NTk3NTk0MzEsImF1ZCI6IjEwODgwNjIxNjM1NzMtaXMwdWQ1aDRza2JscmR1Njp0cnVlLCJheuZXMiLCJpYXQiOjE2NTk3NTk3MzEsImV4cCI6MTY1OTc2MzMzMSwianRpIjoiMDhlNjRhM2I1YzdmNzcxYmRjNTg5M2YwNmMyZjM1ZWZlMzIyNjYyMCJ9.UT07_-_4o_1D5NmVAI0QtXLupVZtXys3Kg0c--Cv-xrMpUZXInfqj142eojvTEf6QBmBPY3k-Mtu7djJAenB8Ed8-dWtvFdGdv5FdSJCSyLN70ObzCsdo_IgjG5r3HTw1C9pIFKggOklJrVN-zL0_Kh3TZdxfMdyEbAUuhIRCreUVgZ74XEWhR6x4l0EY9o2331HcrzAaie_LN4C8NVHhkQ0DLg5dO2v8T1uKG-eTyv-uvjMuhkSVBJR3MnvkGepj7o0h_ELGO9x74P9nNjIKTyZboEr4_YO0BP5aLPwt67LJHactAJ8DJTzugXwaJBVhusK1KPYYGRhy7nTfbfTSg
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C# / .NET 中的服务器端验证 Google Identity Service (GIS) 访问令牌? 的相关文章

随机推荐