Autenticación GCP: RefreshError

Para enviar el correo de prueba de ida y vuelta, envíe un correo electrónico a una bandeja de entrada de GMail e intente verificar su llegada. El mecanismo actual para la autenticación a la API de GMail es bastante estándar, pegado desde la documentación de la API de GMail e integrado en una función:

def authenticate(): """Authenticates to the Gmail API using data in credentials.json, returning the service instance for use in queries etc.""" store = file.Storage('token.json') creds = store.get() if not creds or creds.invalid: flow = client.flow_from_clientsecrets(CRED_FILE_PATH, SCOPES) creds = tools.run_flow(flow, store) service = build('gmail', 'v1', http=creds.authorize(Http())) return service 

CRED_FILE_PATH apunta a un archivo de credenciales descargado para el servicio. La ausencia del archivo token.json desencadena su recreación después de una interacción de autenticación a través de una ventana del navegador, al igual que la caducidad del token.

Esta es una prueba de integración que debe ejecutarse sin cabeza (es decir, sin interacción alguna). Cuando se requiere una nueva autenticación, la prueba actualmente genera una excepción cuando el flujo de autenticación comienza a acceder a sys.argv , lo que significa que ve los argumentos para pytest .

He estado tratando de descubrir cómo autenticar de manera confiable usando un mecanismo que no requiere la interacción del usuario (como una clave API). Nada en la documentación o en Stackoverflow parece responder a esta pregunta.

Un esfuerzo más reciente utiliza el archivo de claves de una cuenta de servicio con la delegación de GMail para evitar los flujos de Oauth2 interactivos.

 def authenticate(): """Authenticates to the Gmail API using data in g_suite_access.json, returning the service instance for use in queries etc.""" main_cred = service_account.Credentials.from_service_account_file( CRED_FILE_PATH, scopes=SCOPES) # Establish limited credential to minimise any damage. credentials = main_cred.with_subject(GMAIL_USER) service = build('gmail', 'v1', credentials=credentials) return service 

Al tratar de utilizar este servicio con

  response = service.users().messages().list(userId='me', q=f'subject:{subject}').execute() 

Yo obtengo:

 google.auth.exceptions.RefreshError: ('unauthorized_client: Client is unauthorized to retrieve access tokens using this method.', '{\n "error": "unauthorized_client",\n "error_description": "Client is unauthorized to retrieve access tokens using this method."\n}') 

Tengo la sensación de que hay algo fundamental que no entiendo.

La cuenta de servicio debe estar autorizada o no puede acceder a los correos electrónicos del dominio.

“El cliente no está autorizado para recuperar tokens de acceso usando este método”

Significa que no lo has autorizado correctamente; check Delegación de autoridad en todo el dominio a la cuenta de servicio

Fuente: el cliente no está autorizado para recuperar tokens de acceso utilizando este método API de Gmail C #