如何解码 google OAuth 2.0 JWT/凭证令牌?

Rom*_*man 8 javascript oauth node.js oauth-2.0 google-oauth

我正在构建一个浏览器应用程序,需要使用链接中概述的 OAuth 2.0/JWT 工作流程向 Google 进行身份验证

在使用 Google OAuth 2.0 成功进行用户身份验证的情况下,Google API 会向应用程序 OAuth 发送如下响应:

{
  "clientId": "xxx...apps.googleusercontent.com",
  "credential": "yyy...123...zzz",
  "select_by": "user"
}
Run Code Online (Sandbox Code Playgroud)

我有一个 client_id 并使用 NodeJS + JS。

用户通过身份验证后,如何向应用程序提供真实的用户数据?

Rom*_*man 7

经过一番反复尝试后,很明显标准import jwt from 'jsonwebtoken'不起作用,Google 使用自己的编码 npm 库 -请在此处google-auth-library查看更多信息。基本解决方案如下:

const { OAuth2Client } = require('google-auth-library')

/**
 * @description Function to decode Google OAuth token
 * @param token: string
 * @returns ticket object
 */
export const getDecodedOAuthJwtGoogle = async token => {

  const CLIENT_ID_GOOGLE = 'yourGoogleClientId'

  try {
    const client = new OAuth2Client(CLIENT_ID_GOOGLE)

    const ticket = await client.verifyIdToken({
      idToken: token,
      audience: CLIENT_ID_GOOGLE,
    })

    return ticket
  } catch (error) {
    return { status: 500, data: error }
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

const realUserData = getDecodedOAuthJwtGoogle(credential) // credentials === JWT token
Run Code Online (Sandbox Code Playgroud)

如果您的令牌(凭据)有效,则realUserData希望具有如下值:

{
  // 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"
}
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用jwt-decode库来解码您的凭据 OAuth 登录,以下是如何使用它的分步说明

  1. 安装jwt-decode

您可以使用npm install jwt-decodeyarn add jwt-decodepnpm install jwt-decode

  1. 导入jwt-decode到您的应用程序

import { GoogleLogin } from '@react-oauth/google';
import jwtDecode from 'jwt-decode'

...

<GoogleLogin 
 onSuccess = {credentialResponse => {
   if (credentialResponse.credential != null) {
    const USER_CREDENTIAL = jwtDecode(credentialResponse.credential);
    console.log(USER_CREDENTIAL);
   }
  }
 }
...

Run Code Online (Sandbox Code Playgroud)

我使用 GoogleLoginOAuth from @react-oauth/google,在我的情况下,这段代码可以工作!

另一件事,** 只是间奏 ** 如果你使用 TypeScript,那么你想要解构对​​象来获取name或者family_name例如


import { GoogleLogin } from '@react-oauth/google';
import jwtDecode from 'jwt-decode'

...

<GoogleLogin 
 onSuccess = {credentialResponse => {
   if (credentialResponse.credential != null) {
    const USER_CREDENTIAL = jwtDecode(credentialResponse.credential);
    console.log(USER_CREDENTIAL);
   }
  }
 }
...

Run Code Online (Sandbox Code Playgroud)

然后你会得到这样的错误曲线

Property 'family_name' does not exist on type 'unknown'
Run Code Online (Sandbox Code Playgroud)

你可以这样写,如果你需要的话复制它

dataCredential.ts

const { given_name, family_name } = USER_CREDENTIAL;
Run Code Online (Sandbox Code Playgroud)

然后你可以让你的代码像这样


import { GoogleLogin } from '@react-oauth/google';
import jwtDecode from 'jwt-decode'
import {dataCredential} from "../types/dataCredential";

...

<GoogleLogin 
 onSuccess = {credentialResponse => {
   if (credentialResponse.credential != null) {
    const USER_CREDENTIAL: dataCredential = jwtDecode(credentialResponse.credential);
    console.log(USER_CREDENTIAL);
    const { given_name, family_name } = USER_CREDENTIAL;
    console.log(given_name, family_name)
   }
  }
 }
...

Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!