Use Google Drive API with google service account from Expo app (react native)

问题描述 投票:0回答:1

I am quite new in app development with Expo (react native). 我正在尝试从我的应用程序(供私人使用)访问Google Drive API,以使该应用程序读取一些在我的Google Drive中特定文件夹中的文件。 I have a google service account active for my app with editor's role. I have shared a specific google drive folder with this service account. 我正在开发构建中使用Expo(不是Expo Go)。

您可以帮助我了解如何在没有用户登录的情况下正确使用Expo应用程序的Google Drive API? 非常感谢!

我阅读了很多文档,并在Chatgpt的帮助下尝试了不同的代码。 建议我使用“ Google-auth-library”(请参见下面的代码),但是在启动应用程序时,我总是会遇到以下错误(我正在在Web浏览器上进行测试):“ Uncaucht TypeError: 原型可能仅是一个对象或null:未定义”。 (删除该代码时,我没有这个错误,所以它确实来自那里)

博览会文档始终将重定向到“@react-native-google-signin/google-signin”库,但chatgpt告诉我,只有在我希望我的用户登录时才可以使用它,情况并非如此(我确实如此)不需要任何用户身份验证,因此使用服务帐户)。

这里是我的代码:

import Constants from 'expo-constants'; import { GoogleAuth } from 'google-auth-library'; import axios from 'axios'; // Extraction des informations du compte de service depuis app.json const { GOOGLE_PROJECT_ID, GOOGLE_CLIENT_EMAIL, GOOGLE_PRIVATE_KEY, GOOGLE_PRIVATE_KEY_ID, GOOGLE_CLIENT_ID, } = Constants.expoConfig?.extra || {}; // Correction de la clé privée qui peut contenir des caractères échappés const privateKeyFormatted = GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n'); /** * Fonction pour authentifier et obtenir un jeton d'accès Google Drive * @returns {Promise<string>} Jeton d'accès à utiliser pour les appels API */ export const authenticateGoogleDrive = async (): Promise<string> => { try { if (!GOOGLE_CLIENT_EMAIL || !GOOGLE_PRIVATE_KEY || !GOOGLE_PROJECT_ID) { throw new Error('Les informations du compte de service sont manquantes'); } console.log("Before GoogleAuth"); console.log("GOOGLE_CLIENT_EMAIL: ", GOOGLE_CLIENT_EMAIL); console.log("privateKeyFormatted: ", privateKeyFormatted); console.log("GOOGLE_PROJECT_ID: ", GOOGLE_PROJECT_ID); // Création de l'objet d'authentification avec uniquement les champs nécessaires const auth = new GoogleAuth({ credentials: { type: 'service_account', project_id: GOOGLE_PROJECT_ID, private_key: privateKeyFormatted, client_email: GOOGLE_CLIENT_EMAIL, }, scopes: ['https://www.googleapis.com/auth/drive'], }); const client = await auth.getClient(); const token = await client.getAccessToken(); if (!token.token) { throw new Error('Impossible d’obtenir le jeton d’accès'); } return token.token; } catch (error) { console.error('Erreur d’authentification Google:', error); throw error; } };

there终于有效的地方:
import Constants from 'expo-constants';
import { KJUR } from 'jsrsasign';


// Charger les variables d'environnement
const GOOGLE_PROJECT_ID = Constants.expoConfig?.extra?.GOOGLE_PROJECT_ID || '';
const GOOGLE_CLIENT_ID = Constants.expoConfig?.extra?.GOOGLE_CLIENT_ID || '';
const GOOGLE_CLIENT_EMAIL = Constants.expoConfig?.extra?.GOOGLE_CLIENT_EMAIL || '';
const GOOGLE_PRIVATE_KEY = (Constants.expoConfig?.extra?.GOOGLE_PRIVATE_KEY || '');
const GOOGLE_PRIVATE_KEY_ID = (Constants.expoConfig?.extra?.GOOGLE_PRIVATE_KEY_ID || '');
const GOOGLE_FOLDER_ID = Constants.expoConfig?.extra?.GOOGLE_FOLDER_ID || '';

const SERVICE_ACCOUNT_EMAIL = GOOGLE_CLIENT_EMAIL;
const PRIVATE_KEY = GOOGLE_PRIVATE_KEY;
const TOKEN_URI = 'https://oauth2.googleapis.com/token';

export async function getAccessToken() {
  const now = Math.floor(Date.now() / 1000);
  const jwtHeader = { alg: 'RS256', typ: 'JWT' };
  const jwtPayload = {
    iss: SERVICE_ACCOUNT_EMAIL,
    scope: 'https://www.googleapis.com/auth/drive.readonly',
    aud: TOKEN_URI,
    exp: now + 3600, // expiration dans 1 heure
    iat: now,
  };

  // Générer le JWT signé en RS256
  const sHeader = JSON.stringify(jwtHeader);
  const sPayload = JSON.stringify(jwtPayload);
  const jwt = KJUR.jws.JWS.sign('RS256', sHeader, sPayload, PRIVATE_KEY);

  // Construire le corps de la requête en x-www-form-urlencoded
  const body = new URLSearchParams();
  body.append('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
  body.append('assertion', jwt);

  const response = await fetch(TOKEN_URI, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: body.toString(),
  });
  const data = await response.json();

  if (!data.access_token) {
    throw new Error(`Erreur lors de la récupération du token : ${JSON.stringify(data)}`);
  }

  return data.access_token;
}
react-native expo google-drive-api service-accounts
1个回答
0
投票

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.