未找到访问令牌受众中的 OAuth2 客户端 ID

Posted

技术标签:

【中文标题】未找到访问令牌受众中的 OAuth2 客户端 ID【英文标题】:OAuth2 client id in access token audience is not found 【发布时间】:2021-02-18 09:31:31 【问题描述】:

首先,我很抱歉我的英语不好。 我使用 Expo 创建了一个 android 应用程序。 我通过 Firebase 实现了 Google 登录。 它没有问题。 为了将结果交付给客户,Firebase 项目的所有权移交给了客户。 我将我的权限更改为编辑。

但是有一个问题。

firebase.auth().signInWithCredential 函数导致错误。 错误代码和信息如下。

auth/invalid-credential OAuth2 client id in access token anaudience 未找到。

我已经用谷歌搜索了错误消息来解决这个问题,但我无法找到它。 这就是我在 Stack Overflow 上写作的原因。

LoginScreen.js

import React,  useEffect, useState  from 'react';
import  Button, Image, ImageBackground, Modal, StyleSheet, Text, TouchableOpacity, View  from 'react-native';
import * as Google from 'expo-google-app-auth';
import firebase from 'firebase'
import  fireAuth, fireStore  from '../Components/FireConfig';
import  screenHeight, screenWidth  from '../Components/Base';
import i18n from 'i18n-js';
import  ActivityIndicator  from 'react-native-paper';
export function LoginScreen( navigation, route ) 

    const [isLoading, setIsLoading] = useState(false)

    // var provider = new firebase.auth.GoogleAuthProvider();

    function isUserEqual(googleUser, firebaseUser) 
        if (firebaseUser) 
            var providerData = firebaseUser.providerData;
            for (var i = 0; i < providerData.length; i++) 
                console.log('providerData[i].providerId', providerData[i].providerId)
                console.log('providerData[i].uid', providerData[i].uid)
                if (providerData[i].providerId === firebase.auth.GoogleAuthProvider.PROVIDER_ID &&
                    // providerData[i].uid === googleUser.getBasicProfile().getId()) 
                    providerData[i].uid === googleUser.user.id) 
                    // We don't need to reauth the Firebase connection.
                    return true;
                
            
        
        return false;
    

    function onSignIn(googleUser) 
        // console.log('Google Auth Response', googleUser);
        // We need to register an Observer on Firebase Auth to make sure auth is initialized.
        var unsubscribe = fireAuth.onAuthStateChanged(function (firebaseUser) 
            unsubscribe();
            // Check if we are already signed-in Firebase with the correct user.
            if (!isUserEqual(googleUser, firebaseUser)) 
                // Build Firebase credential with the Google ID token.
                var credential = firebase.auth.GoogleAuthProvider.credential(
                    //googleUser.getAuthResponse().id_token
                    googleUser.idToken,
                    googleUser.accessToken,
                )
                console.log("credential", credential)
                // Sign in with credential from the Google user.
                fireAuth
                    .signInWithCredential(credential)
                    .then((result) => 
                        const uid = result.user.uid
                        if (result.additionalUserInfo.isNewUser) 
                            fireStore
                                .collection('users')
                                .doc(uid)
                                .set(
                                    google_email: result.user.email,
                                    google_profile_picture: result.additionalUserInfo.profile.picture,
                                    google_locale: result.additionalUserInfo.profile.locale,
                                    google_name: result.additionalUserInfo.profile.name,
                                    created_at: Date.now(),
                                    isPushInfo: false
                                )
                         else 
                            fireStore
                                .collection('users')
                                .doc(uid)
                                .update(
                                    last_logged_in: Date.now()
                                )
                        
                    )
                    .catch((e) => 
                        console.log(e.code, e.message)
                    );
             else 
                console.log('User already signed-in Firebase.', fireAuth.languageCode);
            
        );
    

    async function signInWithGoogleAsync() 
        setTimeout(() => 
            setIsLoading(true)
        , 500)
        try 
            const result = await Google.logInAsync(
                androidClientId : "!!!.apps.googleusercontent.com",
                androidStandaloneAppClientId : "@@@.apps.googleusercontent.com",
                iosClientId : "###.apps.googleusercontent.com",
                iosStandaloneAppClientId : "$$$.apps.googleusercontent.com",
                scopes: ['profile', 'email']
            );
            if (result.type === 'success') 
                console.log(result.type)
                onSignIn(result)
                return result.accessToken;
             else 
                setIsLoading(false)
                console.log(result)
                alert(result)
                return  cancelled: true ;
            
         catch (e) 
            setIsLoading(false)
            console.log(e)
            alert(e)
            return  error: true ;
        
    

    return (
        <View style=styles.container>
                <TouchableOpacity
                    style=
                        alignItems: "center",
                        justifyContent: "center",
                        borderRadius: 10,
                        backgroundColor: "white",
                        width: screenWidth * 0.8,
                        height: 50
                    
                    title="Sign In With Google"
                    onPress=() => 
                        signInWithGoogleAsync();
                     >
                    <Text style= color: "#5887f9" >i18n.t('SignInWithGoogle')</Text>
                </TouchableOpacity>
        </View>
    );


const styles = StyleSheet.create(
    container: 
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
    
)

你可以从下面的链接中看到

https://console.developers.google.com/apis/credentials

app.json


  "expo": 

    ...

    "android": 
      "package": "com.mycompany.myapp",
      "versionCode" : 2,
      "permissions": [
        "READ_EXTERNAL_STORAGE",
        "READ_INTERNAL_STORAGE",
        "WRITE_EXTERNAL_STORAGE",
        "ACCESS_FINE_LOCATION",
        "INTERNET",
        "CAMERA_ROLL",
        "CAMERA"
      ],
      "googleServicesFile": "./google-services.json",
      "useNextNotificationsApi": true,
      "config": 
        "googleMobileAdsAppId": "```",
        "googleSignIn" :
          "apiKey" : "my apiKey",
          "certificateHash" : "11:22:---:11:22"
        
      
    

    ...

  

API 密钥和 OAuth 2.0 客户端 ID 必须按照链接中的内容写入。

期待您的友好合作。

【问题讨论】:

我在现有的大型旧 Android 项目中遇到了同样的问题。它一直运行良好,然后突然没有用户可以登录。 flutter + google_sign_in + firebase auth 出现同样的问题 没有交出像 OP 这样的项目,但类似的错误信息将我引导到这篇文章。发生在使用 firebase_auth 和 google_sign_in 的 Flutter 项目中。应用程序已在 Apple 和 Google 商店上线。停止工作一夜。我删除了“使用 Google 登录”按钮作为实时版本的快速修复。 同样的问题,auth 突然停止工作了。 我对颤振、google_sign_in 和 firebase auth 有完全相同的问题。 【参考方案1】:

关于 GitHub 上的这张票:https://github.com/FirebaseExtended/flutterfire/issues/4053 Google 登录和 Firebase 身份验证存在一个核心问题。我联系了 GCP 支持,几个小时后他们修复了它❤️

【讨论】:

感谢您创建 P1 票证 @FerhatSayan 没问题 ;)

以上是关于未找到访问令牌受众中的 OAuth2 客户端 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何为 OAuth2 访问令牌指定受众?

Spring Boot 2 OIDC(OAuth2)客户端/资源服务器未在 WebClient 中传播访问令牌

Spring安全中的Oauth2客户端

尝试使用spring oauth2中的刷新令牌获取新的访问令牌时出现无效的客户端错误

refresh_token 是不是应该刷新未过期的访问令牌

OAuth2 客户端 ID 和客户端密钥的安全性