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

Jay*_*Jay 8 c# jwt google-oauth json-web-signature

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

\n

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

\n
<script src="https://apis.google.com/js/api:client.js"></script>\ngapi.load();\nvar auth2 = gapi.auth2.init();\nauth2.attachClickHandler();\nonGoogleSignIn(googleUser); // attachClickHandler\'s callback\nvar profile      = googleUser.getBasicProfile(); // profile info accessible\nvar authResponse = googleUser.getAuthResponse(); // auth response accessible\nvar accessToken  = authResponse.id_token; // get actual access token\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
<script src="https://accounts.google.com/gsi/client"></script>\nvar gisClient = google.accounts.oauth2.initTokenClient();\ngisClient.requestAccessToken();\ncallback(); // initTokenClient\'s callback\nvar accessToken = response.access_token; // get access token in callback\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
Payload payload\xc2\xa0=\xc2\xa0await\xc2\xa0GoogleJsonWebSignature.ValidateAsync(accessToken);\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

在线令牌调试器告诉我这不是有效的 JWT 令牌。

\n

ValidateAsync 方法抛出异常:

\n
JWT must consist of Header, Payload, and Signature\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

我还尝试了以下调用:

\n
Payload payload = await JsonWebSignature.VerifySignedTokenAsync(AccessToken, options);\n
Run Code Online (Sandbox Code Playgroud)\n

相同的结果。

\n

官方文档没有说明如何为 C# / .NET 验证此令牌服务器端。

\n

我在文档中找不到有关此问题的帮助。

\n

我可以做什么来让服务器端访问令牌验证\xc2\xa0(以及电子邮件+个人资料的检索)与Google身份服务一起使用?

\n

use*_*357 6

解释

新的 Google 登录返回“ CredentialResponse ”,其中包含一个名为 的属性credential,它是您需要的 base64 格式的 JSON Web 令牌 (JWT)。
该 JWT 可以发送到客户端或服务器进行验证。
验证后您将收到用户个人资料数据。

客户

<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>
Run Code Online (Sandbox Code Playgroud)

服务器(.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
  ...
}
Run Code Online (Sandbox Code Playgroud)

初学者笔记

  1. “唯一用户 ID”位于subjectsub
  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
Run Code Online (Sandbox Code Playgroud)

  • 对于刚接触 Google Sign In 的人来说,这确实需要一些时间来理解。但一旦你了解了基础知识,事情就会变得非常简单。谷歌文档可以提供帮助:https://developers.google.com/identity/gsi/web/guides/handle-credential-responses-js-functions (2认同)