Search code examples
apioauth-2.0google-oauth

How to authenticate a user with their own application, from access credentials in another application?


I've been using OAuth 2.0 to authenticate users to my own application. This was originally for the purpose of "Sign in with Google" and is working fine.

In addition I now want to provide these users with programmatic access to other billable Google Cloud APIs (such as translation) but using their own resources, not those of my application.

What I've tried so far seems to be wrong:

I added the relevant scope URIs as part of the OAuth flow (e.g. https://www.googleapis.com/auth/cloud-translation) then tried accessing the APIs simply by sending an auth header like Authorization: Bearer {access_token}.

This way the user is provided the service, but seemingly via my own application (cloud project) and thus I assume any usage will be paid for by me - not them.

How should this be done properly? How do I go from the access_token for my application to authenticated requests to cloud APIs that the user will be billed for. Presumably the user will have to set up a cloud project and enable the APIs, but that's fine.


Solution

  • Depending on the API, calls can be charged against different projects:

    1. Resource project: That's the project that contains the resource which the API operates on.
    2. Client project: That's the project that contains your OAuth client ID.
    3. User project: This can be any project a user has sufficient access to.

    Many APIs operate on resources that are part of a Google Cloud project (the URL then typically contains a project ID). For these APIs, the default is that they charge the resource project.

    For APIs that don't operate on project resources (like the Cloud Translate API), the default is that they charge the client project.

    You can override this default behavior and specify a custom user project to charge by adding a a X-Goog-User-Project HTTP header to the request. This header must contain:

    a caller-specified project for quota and billing purposes. The caller must have serviceusage.services.use permission on the project.

    The way you authenticate the user looks good, but I suppose adding this header is what's missing.